mid: α -> [α]
mid a = [a]
- mcompose-crossy: (β -> [γ]) -> (α -> [β]) -> (α -> [γ])
- mcompose-crossy f g a = [c | b <- g a, c <- f b]
- mcompose-crossy f g a = foldr (\b -> \gs -> (f b) ++ gs) [] (g a)
- mcompose-crossy f g a = concat (map f (g a))
+ mcompose: (β -> [γ]) -> (α -> [β]) -> (α -> [γ])
+ mcompose f g a = concat (map f (g a))
+ = foldr (\b -> \gs -> (f b) ++ gs) [] (g a)
+ = [c | b <- g a, c <- f b]
-These three definitions are all equivalent.
-In words, `mcompose f g a` feeds the a (which has type α) to g, which
-returns a list of βs; each β in that list is fed to f, which returns a
-list of γs.
+These three definitions are all equivalent. In words, `mcompose f g
+a` feeds the a (which has type α) to g, which returns a list of βs;
+each β in that list is fed to f, which returns a list of γs. The
+final result is the concatenation of those lists of γs.
-The final result is the concatenation of those lists of γs.
For example,
let f b = [b, b+1] in
let g a = [a*a, a+a] in
- mcompose-crossy f g 7 = [49, 50, 14, 15]
+ mcompose f g 7 = [49, 50, 14, 15]
It is easy to see that these definitions obey the monad laws (see exercises).
-There can be multiple monads for any given box type. For instance,
-using the same box type and the same mid, we can define
-
- mcompose-zippy f g a = foldr (\b -> \gs -> f b ++ gs) (g a) []
-
-so that
-
- mcompose-zippy f g 7 = [49, 14]