Які проблеми програмування вирішує Monads? [зачинено]


14

Я читав багато постів, які пояснюють, що таке монади, як unitі як bindпрацюють, деякі з них занурюються прямо в теорію категорій настільки абстрактні (для мене, принаймні, для мене), що змушують кровоточити очі, деякі ігнорують це взагалі і торкаються дивних аналогій буріто, коробки і що ні.

Після декількох тижнів навчання і багато смажених нейронів, (я думаю) я розумію, як працюють Монади. Але все-таки є одне, що уникає мого розуміння, те, що насправді зачіпає кілька постів (крім IO та держави):

ЧОМУ?

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


3
Програми великі та складні. Нам потрібні способи їх структурування. Існує багато способів. Монади - це одне. Стрілки - це одна. Функціонери - це одне. Об'єкти, класи, функції, методи, модулі, ознаки, міксини, пакети - це деякі інші, насправді не зрозуміло, у чому полягає ваш конкретний питання. Ви запитуєте, навіщо нам структурувати програми?
Йорг W Міттаг

1
@ JörgWMittag: Я НЕ питаю, навіщо нам структурувати програми. Очевидно, велика проблема розділена на менші, які ви можете вирішити, а потім об'єднати, щоб отримати рішення для великої. Я запитую, які проблеми вирішує Монад. Є те, що його? Код структуризації? Це все суєта? Наприклад, у Haskell це так, як ви робите I / O. Там монада - це вистава, яка виступає як щось чисте, а насправді це не так. Моє запитання в назві, я не знаю, як це чіткіше заявити.
Dummy Me



1
@RobertHarvey: Я також знайшов перші два посилання, які ви додали, але подобається у відповідях тих та інших публікацій, відповіді прямують до монадів "Можливо", "Держава" та "IO", швидко переходячи до прикладів або коду, і закінчуються "дуже багато проблем, які можна вирішити за допомогою Monads ". Які ще існують проблеми? Я шукаю відповідь вищого рівня, що замість того, щоб повторювати ті самі приклади, насправді йде в корінь проблем (якими б вони не були) і пояснюю, як Монади вирішують їх і чому це найкращий вибір, на відміну від використання чогось іншого. Дуже дякую за відгуки.
Манекен мені

Відповіді:


10

Ви цього не робите потрібні монади, щоб щось вирішити. Вони просто спрощують певні речі. Багато людей виходять занадто абстрактними та теоретичними, коли пояснюють монади. Здебільшого, монади - це зразок, який виникає знову і знову в програмуванні. Розпізнаючи цей шаблон, ми можемо спростити наш код і уникнути повторного виконання певних функцій.

Для Хаскелла, з конкретної точки зору, найвідоміше, що монади дозволяють - це позначення . Ознайомлення зі списками в Хаскелл та інших мовах також сильно користуються монадами. Ви також можете створювати такі бібліотеки Control.Monad .

Усі вони надають корисні спрощення, і коли ви реалізуєте його за одну монаду, ви автоматично отримаєте її для всіх монад. Це одна з основних причин повторного використання коду для функціонального програмування набагато простіше, ніж інші парадигми.


2
Насправді я б сказав, що найвідоміше, що ввімкнули монади haskell - це простий спосіб отримати ефекти IO, які реально працюють так, як ви очікуєте. Я думаю, що кожен, хто цікавиться, що дають нам монади, повинен спробувати Міранду . Міранда - це мова, яку Haskell покликала замінити, і її слід дуже легко вивчити для тих, хто має досвід Haskell. Основна відмінність полягає в тому, що він не має монадичного IO, що робить мову набагато складніше, ніж Haskell, для будь-якого нетривіального проекту.
Жуль

Так, IOце найвідоміша монада Хаскелла , але я не перелічував прикладів окремих монад. Я перелічував приклади загальних абстракцій, які вони дозволяють. Я намагався розібратися, чому, наприклад, перший хлопець, який задумався про використання монади для IO, вважає, що це взагалі гарна ідея.
Карл Білефельдт

1
@Jules: Або подивіться на історію Haskell. До Monads дизайнери Haskell експериментували з Lazy Streams і Continuations як основою для вводу-виводу, і обидва їх було важко використовувати.
Йорг W Міттаг

5

Легше зрозуміти, якщо подивитися на конкретні монади і побачити, які проблеми вони вирішують. Наприклад, у Haskell:

  • IO: Дозволяє представляти IO у системі типів, тому ви можете очистити окремі функції від функцій, що виконують IO.

  • Список: Дозволяє робити розуміння списку та недетерміновані обчислення.

  • Можливо: краща альтернатива нулю та підтримка чогось порівнянного з оператором з’єднання нулів C #.

  • Парсек: зручний DSL для написання парсерів.

Тож легко (сподіваюсь) побачити обґрунтування окремих монад, оскільки всі вони дуже корисні. Але проблеми, які вони вирішують, також є зовсім різними, і, маючи на увазі, вони, схоже, не мають багато спільного, за винятком того, що вони пов'язані з деякою логікою ланцюгових операцій. Монади корисні, оскільки дозволяють будувати таку різноманітність інструментів.

Чи можна вищенаведені приклади реалізувати без монад? Безумовно, вони можуть бути реалізовані спеціально, але монади, вбудовані в мову, дозволяють підтримувати пряму мову, як do-нотація, яка працює з усіма монадами.


2

Одне, що робить це заплутаним, - це те, що "популярні" функції, як bindі<*> орієнтовані на практику. Але для розуміння понять простіше спочатку подивитися на інші функції. Варто також зазначити, що монади виділяються, оскільки вони трохи завищені в порівнянні з іншими пов'язаними поняттями. Тому я почну замість цього функторів.

Функціонери пропонують функцію (у позначенні Haskell) fmap :: (Functor f) => (a -> b) -> f a -> f b. Іншими словами, у вас є контекст, в fякий ви можете підняти функцію. Як ви можете собі уявити, майже все є функтором. Списки, може бути, або функції, введення / виведення, кортежі, парсери ... Кожен представляє контекст, в якому може з’являтися значення. Таким чином, ви можете написати надзвичайно універсальні функції, які працюють практично в будь-якому контексті, використовуючи fmapабо його вбудований варіант <$>.

Які ще речі ви хочете робити з контекстами? Ви можете поєднати два контексти. Отже, ви можете отримати узагальнення, zip :: [a] -> [b] -> [(a,b)]наприклад, подібне:pair :: (Monoidal f) => f a -> f b -> f (a,b) .

Але оскільки це ще корисніше на практиці, бібліотеки Haskell натомість пропонують Applicative, що є комбінацією Functorта Monoidal, а також Unit, що просто додає, що ви можете фактично поставити значення "всередині" свого контексту unit.

Ви можете написати надзвичайно загальні функції, просто вказавши ці три речі про контекст, в якому ви працюєте.

Monadце лише інша річ, яку ви можете стверджувати над цим. Те, про що я раніше не згадував, - це те, що у вас вже є два способи поєднання двох контекстів: Ви можете не тільки pairїх, але також можете складати їх, наприклад, ви можете мати список списків. У контексті вводу-виводу прикладом може бути дія вводу-виводу, яка може читати інші дії вводу-виводу з файлу, тож у вас буде тип FilePath -> IO (IO a). Як ми можемо позбутися цієї укладання для отримання виконуваної функції IO a? Ось звідки входить Monads join, це дозволяє нам поєднувати два складених контексти одного типу. Те саме стосується парсерів, може бути і т. Д. І bindце просто більш практичний спосіб використанняjoin

Отже, монадичний контекст повинен пропонувати лише чотири речі, і він може бути використаний майже з усіма механізмами, розробленими для вводу / виводу, для парсерів, відмов тощо.


1

Monads дозволяє виражати різні нечисті обчислення, а також спрощує код

  • обчислювальний стан (отримати / встановити стан через монаду)
  • I / O (журнал, користувальницький інтерфейс, файл або просто створюють / споживають список X)
  • Також "нелінійний" контрольний потік (тобто винятки, можливо, тощо)

І, що важливо, не роблячи компромісів із чистими мовними конструкціями та не отримуючи з нього чистішої мови


2
Щоправда - але це лише частина того, для чого використовуються монади. Перелічіть розуміння або Maybeне пов'язані ні з чим зовнішнім.
ЖакB

Було б корисно, якби тварини пояснили, чому вони так зробили. Я не бачу нічого поганого в цій відповіді.
Жуль

@JacquesB, однак, вони значущі.
Жуль

1
Світові типи, типи унікальності, лінійні типи дозволяють вам це робити.
Йорг W Міттаг

@Jules Списки як монада недетермінізму є надзвичайною? Чи можете ви уточнити, що таке ваше поняття "державний"?
Джек
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.