Jedną z rzeczy, która sprawia, że jest to mylące, jest to, że „popularne” funkcje jak bind
i <*>
są zorientowane na praktykę. Ale aby zrozumieć pojęcia, łatwiej jest najpierw spojrzeć na inne funkcje. Warto również zauważyć, że monady wyróżniają się, ponieważ są nieco przesadzone w porównaniu do innych powiązanych koncepcji. Zacznę więc od funktorów.
Functors oferują funkcję (w notacji Haskell) fmap :: (Functor f) => (a -> b) -> f a -> f b
. Innymi słowy, masz kontekst f
, w którym możesz podnieść funkcję. Jak możesz sobie wyobrazić, prawie wszystko jest funktorem. Listy, być może, albo funkcje, I / O, krotki, parsery ... Każdy przedstawia kontekst, w którym może pojawić się wartość. Możesz więc pisać niezwykle wszechstronne funkcje, które działają w prawie każdym kontekście, używając fmap
lub jego wbudowanego wariantu <$>
.
Jakie inne rzeczy chcesz robić z kontekstami? Możesz połączyć dwa konteksty. Więc może chcesz uzyskać uogólnienie zip :: [a] -> [b] -> [(a,b)]
na przykład tak: pair :: (Monoidal f) => f a -> f b -> f (a,b)
.
Ale ponieważ jest to jeszcze bardziej przydatne w praktyce, biblioteki Haskell oferują zamiast tego Applicative
, co jest kombinacją Functor
i Monoidal
, A także Unit
, co po prostu dodaje, że możesz w rzeczywistości umieścić wartości „wewnątrz” swojego kontekstu unit
.
Możesz pisać niezwykle ogólne funkcje, po prostu podając te trzy rzeczy na temat kontekstu, w którym pracujesz.
Monad
to po prostu kolejna rzecz, którą można dodać do tego. To, czego wcześniej nie wspomniałem, to to, że masz już dwa sposoby łączenia dwóch kontekstów: możesz nie tylko pair
je, ale możesz także układać w stosy, np. Możesz mieć listę list. W kontekście We / Wy przykładem może być akcja We / Wy, która może odczytać inne akcje We / Wy z pliku, więc masz typ FilePath -> IO (IO a)
. Jak możemy pozbyć się tego stosu, aby uzyskać funkcję wykonywalną IO a
? Tam właśnie pojawia się Monad
s join
, pozwala nam połączyć dwa konteksty tego samego typu. To samo dotyczy parserów, może itd. I bind
jest po prostu bardziej praktycznym sposobem użyciajoin
Tak więc kontekst monadyczny musi oferować tylko cztery rzeczy i może być używany z prawie wszystkimi maszynami opracowanymi dla I / O, parserów, awarii itp.