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.