[Haskell-cafe] Grokking monads by not overlooking concatMap
Achim Schneider
barsoap at web.de
Mon May 5 07:39:20 EDT 2008
guard True = return ()
guard False = []
-- the textbook example
f = do
x <- [1..4]
y <- [2..8]
guard (x*y==8)
return (x,y)
-- the translation.
f' = [1..4] >>= (\x ->
[2..8] >>= (\y ->
(if (x*y == 8) then return () else []) >>
return (x,y)))
-- another one. note that we can move the final
-- return out of the parens. It would even work without it, but we'd
-- get a list containing many empty lists: concat fixes that.
f'' = [1..4] >>= (\x ->
[2..8] >>= (\y ->
if (x*y == 8) then [(x,y)] else [] >>= return ))
-- bind desugared. Actually, it seems to be impossible to
-- write this in monadic notation and I'm getting quite confused.
f''' = concatMap
(\x -> concatMap
(\y -> if x*y == 8 then [(x,y)] else [])
[2..8])
[1..4]
-- That's the one I've been looking for. Remember that
-- return e = [e]
f'''' = concatMap
(\x -> concatMap
(\y -> concatMap
(\_ -> [(x,y)])
(if x*y == 8 then [()] else []))
[2..8])
[1..4]
Morale: Premature term elimination is the root of all misunderstanding.
Haskell wins the wickedness of design contest by using [()] and [] as
truth values.
--
(c) this sig last receiving data processing entity. Inspect headers for
past copyright information. All rights reserved. Unauthorised copying,
hiring, renting, public performance and/or broadcasting of this
signature prohibited.
More information about the Haskell-Cafe
mailing list