Search code examples
haskellio-monad

Haskell. Why it is working? (Iteration over Monad)


liftMM :: Monad m => (a -> b) -> m a -> m b
liftMM f m = m >>= \a -> return (f a)

I run:

> liftMM (*2) [1..10]

I got output:

> [2,4,6,8,10,12,14,16,18,20]

I can not see how this function is mapping over all list's values? There is no any recursion or iteration, just one pass monad internal m value to the function f. What I am missing here?


Solution

  • m here is [] and liftMM works by delegating to the implementation of (>>=) and return for m. Therefore you need to understand (>>=) and return for lists, and if you look at the definition they are:

    instance Monad []  where
        xs >>= f            = [y | x <- xs, y <- f x]
        return x            = [x]
    

    so for each element in the source list >>= applies f and then inserts each element of the returned list into the result list.

    return x simply returns a singleton list containing x so return (f a) returns a list [f a]. Each of these single element lists are then combined by (>>=) to create the output list.