Reputation: 1304
I'm having little trouble translating this do
statement :
ex10 :: [Int]
ex10 = do
num <- [1..20]
guard (even num)
guard (num `mod` 3 == 0)
return num
into some kind of monad
syntax like this :
ex10' :: [Int]
ex10' = [1..20] >>= (guard . even) >>= (guard . (==0) . (mod 3)) >>= \r -> return r
This doesn't work, and I'm not quite sure why. I think I might have misunderstood guard
but am not sure in what way.
Upvotes: 3
Views: 370
Reputation: 144206
guard
has type MonadPlus m => Bool -> m ()
so your third segment
(guard . (==0) . (mod 3))
receives a value of type ()
which is not what you want. In do
notation
do
guard (even num)
guard (num `mod` 3 == 0)
is desugarded into something like
guard (even num) >> guard (num `mod` 3 == 0)
so you can implement ex10'
as
ex10' = [1..20] >>= (\num -> (guard $ even num) >> (guard $ num `mod` 3 == 0) >> return num)
Upvotes: 4