sequence :: Monad m => [m a] -> m [a]
sequence = mapM id
sequence [a, b, ..., c] = do
x <- a
y <- b
...
z <- c
return [x, y, ..., z]
mapM :: Monad m => (a -> m b) -> [a] -> m [b]
mapM f = sequence . map f
mapM f [a, b, ..., c] = do
x <- f a
y <- f b
...
z <- f c
return [x, y, ..., z]
foldr f z xs
replaces every (:)
in xs
with f
, and the []
with z
.
This also explains how foldr (:) []
is the identity on lists: it replaces
(:)
with (:)
and []
with []
.
-- (\x acc -> newAcc) -> initialValue -> list -> result
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr f z (x1 : x2 : x3 : ... : []) = x1 `f` (x2 `f` ... (xn `f` z)...))
Graphical version:
: f
/ \ / \
1 : foldr f z 1 f
/ \ ==> / \
2 : 2 f
/ \ / \
3 : 3 f
/ \ / \
4 [] 4 z
-- (\acc x -> newAcc) -> initialValue -> list -> result
foldl :: (a -> b -> a) -> a -> [b] -> a
foldl f z [x1, x2, ..., xn] == (...((z `f` x1) `f` x2) `f`...) `f` xn
== f ( ... (f (f (f (f z x1) x2) x3) x4) ...) xn
Graphical version:
: f
/ \ / \
1 : foldl f z f 4
/ \ ==> / \
2 : f 3
/ \ / \
3 : f 2
/ \ / \
4 [] z 1
foldM
is like foldl, but the accumulator is monadic.
foldM :: Monad m => (a -> b -> m a) -> a -> [b] -> m a
foldM f a1 [x1, x2, ..., xm] = do
a2 <- f a1 x1
a3 <- f a2 x2
...
f am xm
Another way of seeing it is as a chain of >>=
:
foldM f a1 [x1, x2, ..., xm] = let f' = flip f
in return a1 >>= f' x1
>>= f' x2
...
>>= f' xm
filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
filterM _ [] = return []
filterM p (x:xs) = do
flag <- p x
ys <- filterM p xs
return (if flag then x:ys else ys)
-
A
do
block with a single action as its content is equivalent to not having thedo
keyword:.do action ----> action
-
The
<-
symbol desugars to a>>=
(pronounced »bind«) operator:do x <- action ----> action >>= \x -> do REST REST
-
An action not bound via
<-
is desugared to the>>
operator:do action ----> action >> do REST REST
-
The standalone
let
indo
notation is translated to alet…in…
block:do let definition = value ----> let definition = value in do REST REST