Принципы, лучшие практики и шаблоны проектирования для функционального программирования - PullRequest
22 голосов
/ 09 мая 2009

Существуют ли известные принципы, передовые практики и шаблоны проектирования, которым можно следовать при написании кода на функциональном языке программирования?

Ответы [ 7 ]

20 голосов
/ 09 мая 2009

Есть складки, разворачивания, карты и т. Д.

Я рекомендую использовать их как лучший опыт, так как их поведение довольно легко рассуждать, и они часто сообщают о цели функции (например, просто взгляните на знаменитый Evolution of a Haskell Programmer). и противопоставить первокурсника и старшему, и профессору).

10 голосов
/ 09 мая 2009

Шаблон проектирования: пусть типы управляют вашим кодированием .

  1. Выясните, какой тип вы пытаетесь вернуть.

  2. Знайте, что определенные конструкторы типов поставляются с определенным синтаксисом, и используйте его, чтобы уменьшить требуемый тип. Вот два примера:

    • Если вы пытаетесь вернуть тип функции T1 -> T2, всегда безопасно писать

      \ x -> ...
      

      Теперь в теле вы пытаетесь создать значение типа T2, который является меньшим типом, плюс вы получили дополнительное значение x типа T1, которое может упростить вашу работу.

      Если лямбда оказывается ненужной, вы всегда можете уменьшить ее позже.

    • Если вы пытаетесь создать пару типа (T1, T2), вы всегда можете попытаться создать значение x типа T1 и значение y типа T2, тогда пара (x, y). Опять же, вы уменьшили проблему до проблемы с более мелкими типами.

  3. Как только типы станут настолько малыми, насколько вы сможете их создать, посмотрите на типы всех переменных let-bound и lambda-bound в области видимости и посмотрите, как вы можете получить значение нужного вам типа. Обычно вы ожидаете использовать все аргументы для всех функций; если вы этого не сделаете, убедитесь, что вы можете объяснить, почему.

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

8 голосов
/ 09 мая 2009

Рекомендация: используйте алгебраические типы данных и воспользуйтесь полной проверкой из компилятора сопоставления с образцом. В частности,

  • Никогда не совпадать с шаблоном подстановки _ на верхнем уровне.

  • Установите параметры компилятора таким образом, чтобы отсутствующий регистр в сопоставлении с образцом был ошибкой, а не предупреждением.

7 голосов
/ 09 мая 2009

Не следуй принципам, следуй за своим носом. Держите функции короткими. Ищите способы уменьшить сложность кода, что часто, но не обязательно, означает самый лаконичный код. Узнайте, как использовать встроенные функции высшего порядка.

Рефакторинг и уменьшение размера кода функции сразу после написания. Это экономит время, потому что завтра у вас уже не будет проблем и решения.

4 голосов
/ 09 мая 2009

Шаблон проектирования: позвольте компилятору выводить типы для ваших функций и убедитесь, что эти типы в точности соответствуют вашим ожиданиям. Если типы являются более полиморфными или менее полиморфными, выясните, почему.

Например, если вы пишете функцию сортировки в Haskell, ожидайте

Ord a => [a] -> [a]

Если ваш тип

Num a => [a] -> [a]

или

[a] -> b

тогда что-то ужасно не так.

Рекомендация: как только вы подтвердите компилятором, что тип соответствует вашему, поставит явную сигнатуру типа для каждой функции верхнего уровня . (Или, если вы используете ML или Caml, напишите явный интерфейс.) Установите параметры компилятора, чтобы значения с отсутствующими сигнатурами вызывали ошибку.

3 голосов
/ 26 августа 2012

Я бы ответил, возможно, немного расплывчатым принципом: стремиться сделать ваш код красивым как самый важный аспект. цитата Дэвид Гелернтер:

Красота важнее в вычислениях, чем где-либо еще в технологиях, потому что программное обеспечение очень сложно. Красота - высшая защита от сложности.

и Брайан Керниган:

Управление сложностью - это сущность компьютерного программирования.

Если вы преследуете эту цель, это приведет вас к написанию кода, который будет простым для чтения и понимания (что очень важно) кода, который разбит на маленькие компактные части с четко определенной целью. Это поможет вам научиться лучше выражать свои мысли на определенном языке.

(Все это относится не только к функциональным языкам, но написание красивого кода в них намного проще.)

2 голосов
/ 09 мая 2009

Почему функциональное программирование имеет значение Джона Хьюза (John Hughes) дает хорошую мотивацию для того, почему функции лени и высшего порядка (первого класса) предоставляют множество менее функциональных языков, отсутствующих, и дополняются шаблонами проектирования .

В контексте Haskell я подумал, что книга Real World Haskell содержит несколько полезных и практических советов по идиомам, абстракциям и классам типов и тому подобному. Typeclassopedia также всегда полезен. Основные, очень абстрактные классы типов можно рассматривать как шаблоны проектирования, за исключением того, что они применяются системой компилятора / типа и частью языка (если вы научитесь их использовать).

В контексте Lisp Пол Грэм написал книгу под названием On Lisp ( доступна онлайн ), в которой он показывает, что функциональные языки идеальны для создания собственного языка программирования, а затем пишут свою программу на этом языке. Таким образом, встроенные доменные языки сами по себе являются своего рода шаблоном проектирования.

...