Jedną z rzeczy, która sprawia, że jest to mylące, jest to, że „popularne” funkcje jak bindi <*>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 fmaplub 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ą Functori 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.
Monadto 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 pairje, 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ę Monads join, pozwala nam połączyć dwa konteksty tego samego typu. To samo dotyczy parserów, może itd. I bindjest 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.