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