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