list monad and filterM

I don't get this example ( from Learn you a Haskell http://learnyouahaskell.com/for-a-few-monads-more ). The question is about filterM and the List Monad
import Control.Monad ( filterM ) powerset :: [a] -> [[a]] powerset xs = filterM (\x -> [True, False]) xs
Looking into Control.Monad, filterM is defined: filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a] filterM _ [] = return [] filterM p (x:xs) = do flg <- p x ys <- filterM p xs return (if flg then x:ys else ys) Ok, let's do it step by step.
test = powerset [1,2,3]
'p' (in the filterM function) is p = \x -> [True, False] so flg is [True, False] Let's not calculate ys for a second, but go directly to the return function. return (if [True, False] then x:ys else ys) I expect the above code to throw a "Couldn't match expected type `Bool' with actual type `[Bool]'" So I can't see how the trick works! Any hint?

On Fri, Apr 06, 2012 at 04:58:02PM +0200, franco00@gmx.com wrote:
I don't get this example ( from Learn you a Haskell http://learnyouahaskell.com/for-a-few-monads-more ). The question is about filterM and the List Monad
import Control.Monad ( filterM ) powerset :: [a] -> [[a]] powerset xs = filterM (\x -> [True, False]) xs
Looking into Control.Monad, filterM is defined:
filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a] filterM _ [] = return [] filterM p (x:xs) = do flg <- p x ys <- filterM p xs return (if flg then x:ys else ys)
Ok, let's do it step by step.
test = powerset [1,2,3]
'p' (in the filterM function) is
p = \x -> [True, False]
so flg is [True, False]
No, flg is not [True, False]. <- is not assignment. It gets translated into a call to (>>=) (bind). Given the way (>>=) works for the list monad, flg will be first True, and then False. -Brent
participants (2)
-
Brent Yorgey
-
franco00@gmx.com