Як ви проектуєте програми на Haskell або інших функціональних мовах програмування?


52

У мене є досвід роботи з об'єктно-орієнтованими мовами програмування, такими як c # або ruby. Я знаю, як проектувати програму в об'єктно-орієнтованому стилі, як створювати класи та об'єкти та як визначати відносини між ними. Я також знаю деякі схеми дизайну.

Як люди пишуть функціональні програми? Як вони починаються? Чи існують шаблони дизайну функціональних мов? Чи застосовуються методології, як екстремальне програмування, або гнучка розробка для функціональних мов?


1
Пов'язаний з цим питання: stackoverflow.com/questions/3077866 / ...
HaskellElephant

Відповіді:


24

Свою відповідь я пишу в основному, маючи на увазі Haskell, хоча багато понять однаково добре застосовуються до інших функціональних мов, таких як 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 просто містить їх у монадах, щоб їх вплив можна було обмежити та спостерігати.

tl; dr Grokking функції вищого порядку і монади - це еквівалент Haskell, що відповідає моделям дизайну grokking. Після того, як ви засвоїте ці поняття Haskell, ви почнете думати, що «дизайнерські шаблони» - це здебільшого дешеві шляхи вирішення, що імітують силу Haskell.

Чи застосовуються методології, як екстремальне програмування, або гнучка розробка для функціональних мов?

Я не бачу нічого, що зв'язує ці стратегії управління з будь-якою парадигмою програмування. Як зазначає фінфо, функціональне програмування практично змушує вас робити функцію декомпозиції, розбиваючи велику проблему на підпроблеми, тому міні-віхи повинні бути шматочком пирога. Є такі інструменти, як QuickCheck і Zeno, щоб перевірити або навіть довести властивості щодо функцій, які ви пишете.


"Я міг би пояснити, але світові насправді не потрібна ще одна аналогія монади". - Нам завжди потрібно більше аналогій з монадами, і ваша - одна з найкращих, що я бачив.
Адам Гент

1
Чудова відповідь, але я думаю, що ваше обговорення моделей дизайну трохи вводить в оману. У той час як вам не потрібні шаблони дизайну в стилі OO / GOF в Haskell - насправді було б смішно намагатися на них - самі візерунки - це просто способи спілкування громадою з рішеннями проблем, які виникають знову і знову. Спільнота Haskell ще дуже молода, тому ще не так багато моделей, про які можна говорити, але якщо ви запитаєте мене про приклади моделей Haskell, я б згадав такі речі, як GADTs або Arrowized FRP.
rtperson
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.