let
po prostu przydziela nazwę lub dopasowuje wzorce do dowolnych wartości.
Dla <-
, niech najpierw krok od (naprawdę nie) tajemnicze IO
monady, ale uważają, że monady mają pojęcie „pojemnik”, takie jak listy lub Maybe
. Wtedy <-
nie zajmuje się "rozpakowaniem" elementów tego kontenera. Odwrotną operacją "odkładania" jest return
. Rozważ ten kod:
add m1 m2 = do
v1 <- m1
v2 <- m2
return (v1 + v2)
"Rozpakowuje" elementy dwóch pojemników, dodaje wartości razem i zawija je ponownie w tej samej monadzie.Współpracuje z list, z uwzględnieniem wszystkich możliwych kombinacji elementów:
main = print $ add [1, 2, 3] [40, 50]
--[41,51,42,52,43,53]
W rzeczywistości w przypadku list można napisać także add m1 m2 = [v1 + v2 | v1 <- m1, v2 <- m2]
. Ale nasza wersja współpracuje z Maybe
s, zbyt:
main = print $ add (Just 3) (Just 12)
--Just 15
main = print $ add (Just 3) Nothing
--Nothing
Teraz IO
nie różni się w ogóle. Jest to pojemnik o pojedynczej wartości, ale jest to "niebezpieczna" nieczysta wartość, taka jak wirus, którego nie wolno nam bezpośrednio dotykać. do
-Block jest tutaj naszą szklaną obudową, a <-
są wbudowanymi "rękawicami" do manipulowania przedmiotami wewnątrz. Dzięki return
dostarczamy pełny, nienaruszony kontener (a nie tylko niebezpieczną zawartość), kiedy jesteśmy gotowi. Nawiasem mówiąc, funkcja add
działa również z wartościami IO
(które otrzymaliśmy z pliku lub z wiersza poleceń lub generatora losowego ...).