Я пишу свой ответ в основном с мыслью о Хаскеле, хотя многие концепции одинаково хорошо применимы и к другим функциональным языкам, таким как Erlang, Lisp (s) и ML. Некоторые даже применяются (в некоторой степени) к Ruby, Python, Perl и Javascript.
Как люди пишут функциональные программы? Как они начинаются?
Написание функций. Когда вы занимаетесь функциональным программированием, вы либо пишете main
, либо пишете вспомогательную функцию. Иногда вашей главной целью может быть написание типа данных с различными соответствующими функциями, которые работают с ним.
Функциональное программирование очень хорошо подходит как для нисходящего, так и для восходящего подходов. Haskell настоятельно рекомендует писать ваши программы на языке высокого уровня, а затем просто определять детали вашего проекта высокого уровня. Смотрите minimum
, например:
minimum :: (Ord a) => [a] -> a
minimum xs = foldl1 min xs
Функция поиска наименьшего элемента в списке записывается просто как обход списка, используя функцию min для сравнения каждого элемента с «аккумулятором» или текущим минимальным значением.
Существуют ли шаблоны проектирования для функциональных языков?
Есть две вещи, которые можно приравнять к «шаблонам проектирования», imho, функциям высшего порядка и монадам . Давайте поговорим о первом. Функции высшего порядка - это функции, которые либо принимают другие функции в качестве входных данных, либо создают функции в качестве выходных данных. Любой функциональный язык обычно делает интенсивное использование map
, filter
иfold
(сворачивание часто также называют «уменьшить»): три очень основные функции высшего порядка, которые применяют функцию к списку различными способами. Они заменяют шаблон для петли красивым способом. Передача функций в качестве параметров является чрезвычайно мощным благом для программирования; Многие «шаблоны проектирования» можно выполнить проще, используя функции высшего порядка, возможность создавать свои собственные и использовать мощную стандартную библиотеку, которая полна полезных функций.
Монады - "более страшная" тема. Но на самом деле они не такие страшные. Мой любимый способ думать о монадах - думать о них как об обертывании функции в пузыре и придании этой функции сверхспособностей (которые работают только внутри пузыря). Я мог бы уточнить, но миру действительно не нужна еще одна аналогия с монадой. Поэтому я перейду к быстрым примерам. Предположим, я хочу использовать недетерминированный «шаблон дизайна». Я хочу выполнить одно и то же вычисление для разных входов одновременно. Я не хочу выбирать только один вход, я хочу выбрать их все. Это будет список монада:
allPlus2 :: [Int] -> [Int]
allPlus2 xs = do x <- xs
return (x + 2)
Теперь, идиоматический способ сделать это на самом деле map
, но ради иллюстрации, вы можете увидеть, как монада списка позволила мне написать функцию, которая выглядит так, как будто она работает с одним значением, но наделила ее сверхдержавой для работы с каждым элементом в список? Другие сверхдержавы включают отказ, состояние, взаимодействие с «внешним миром» и параллельное выполнение. Эти сверхспособности очень мощные, и большинство языков программирования позволяют функциям со сверхспособностями распространяться повсюду. Большинство людей говорят, что Haskell вообще не допускает этих сверхдержав, но на самом деле Haskell просто содержит их в монадах, поэтому их эффект можно ограничить и наблюдать.
Dr Grokking функции и монады высшего порядка - это эквивалент Хаскелла для шаблонов проектирования гроккинга. Как только вы изучите эти концепции Haskell, вы начнете думать, что «шаблоны проектирования» - это в основном дешевые обходные пути для имитации возможностей Haskell.
Применимы ли методологии, такие как экстремальное программирование или гибкая разработка, к функциональным языкам?
Я не вижу ничего, что связывало бы эти стратегии управления с какой-либо одной парадигмой программирования. Как сказал phynfo, функциональное программирование фактически вынуждает вас выполнять декомпозицию функций, разбивая большую проблему на подзадачи, поэтому мини-этапы должны быть простыми. Существуют такие инструменты, как QuickCheck и Zeno для тестирования или даже проверки свойств написанных вами функций.