简体   繁体   中英

List instance of monad in Haskell - why use concat in bind-operation?

I found some question here: Redefining monad list instance . I'm currently trying to get my head wrapped around monads. But I need some help here, I don't get the instance-definition of lists as monads.

This is my given definition of a list-instance for a monad:

    instance Monad [] where
    xs >>= f = concat $ map f xs
    return x = [x]
    fail _ = []

I dont understand, why I need concat in the bind-function. This is my definition of (>>=) :

    (>>=) :: Monad m => m a -> (a -> m b) -> m b

So I have some monadic value ma and a function, taking a value a and producing a monadic value mb given as parameters. I 'feed' a from ma into the function (a -> mb) and thus get a monadic value mb as a result. In my own words: The bind-operator (>>=) allows to chain monadic functions (returning monadic values) where the value of the output of the earlier function is the input for the next function. Right?

Back to the list-instance. map f xs uses the function f on every value in xs . So map (*2) [1,2,3] results in [2,4,6] . And that's all I wanted here or not? How should I use concat here? The definition of concat is as follows:

    concat :: [[a]] -> [a]

Why do I get a list of lists in the (>>=) -function? Is it because list is the monad and I take every single value from that list to feed it to f and map just gets singleton-inputs? But how do I iterate over the whole list then? Where does the 'picking each value' happen? And if map takes the whole list xs as input (that's how I understand it) why should I get a list of lists?

If

x :: [a]
f :: a -> [b]

then

map f :: [a] -> [[b]]
map f x :: [[b]]

so, we need to flatten the latter into [b] . This is done by concat .

Note how f was already producing a list, so map makes that into a list-of-lists. This is crucial: if f was not producing a list but were f :: a->b , then we don't need concat -- we don't even need a monad, since a functor providing fmap=map :: (a->b) -> [a] -> [b] would be enough.

The added benefit of a monad over a functor mainly lies in letting f produce a value in a monadic type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM