Перед чтением обратите внимание, что предварительное знание Haskell или функционального программирования не требуется.

Статья

Недавно я экспериментировал с Haskell, и мне особенно понравилась одна функция — (x:xs) в сопоставлении с образцом списков, где x — текущий элемент, так называемая «голова», а xs — остальная часть. список, так называемый «хвост». Ниже приведен пример, который включает в себя упомянутую функцию, метод длины для списков:

При этом я начал задаваться вопросом, будет ли полезна реализация этой функции на другом языке или нет. Следующий фрагмент кода — это попытка «имитировать» его в Swift:

Как видите, эти два метода являются расширениями типа «Массив».

Первый, который я называю — потому что я не мог придумать лучшего имени — recurse, возвращает кортеж, состоящий из необязательного элемента с именем x и остальной части массива с именем xs. X необязателен, потому что в какой-то момент может не остаться фактического элемента. Его тело говорит само за себя: self.first — это текущая голова, а self.dropFirst вернет «хвост». Однако возвращаемый тип dropFirst — это ArraySlice, а не Array, отсюда и метод карты.

Теперь, когда функция Haskell в некоторой степени имитируется, пришло время реализовать длину. Общий сценарий состоит в том, чтобы вернуть 1 плюс то, что приводит к использованию длины хвоста текущей «итерации», см. пример 2, l. 9. Две строки над ним — это случаи, когда список пуст и возвращает 0, или элемент head не существует, то есть он равен null и возвращает только 1.

Эта реализация отлично работает и в чем-то мне нравится, хотя она и не такая элегантная, как оригинал на Haskell. Лично я не вижу преимуществ в таком подходе к рекурсии в таком языке, как Swift, как и некоторые из моих друзей, которые знают Swift. Тем не менее, это шаблон дизайна, который может понравиться некоторым.

Первоначально опубликовано на странице https://lukasam.com/programming/haskell/swift/2018/02/04/imitating-haskells-list-pattern.html 4 февраля 2018 г.