Using return vs. not using return in the list monad

后端 未结 6 673
Happy的楠姐
Happy的楠姐 2020-11-27 05:50

I started my Grand Haskell Crusade (GHC :) ) and I am a bit confused with monads and IO functions. Could anyone explain simply what is the difference between those

6条回答
  •  感动是毒
    2020-11-27 06:32

    Desugaring the do syntax to the equivalent

    f1 = [1,2] >>= \x -> [x, x+1]
    f2 = [1,2] >>= \x -> return [x, x+1]
    

    Now, >>= comes from the Monad class,

    class Monad m where
        (>>=) :: m a -> (a -> m b) -> m b
        return :: a -> m a
    

    and the LHS of >>= in both f1 and f2 is [a] (where a has defaulted to Integer), so we're really considering

    instance Monad [] where
        (>>=) :: [a] -> (a -> [b]) -> [b]
        ...
    

    This obeys the same monad laws as, but is a different monad from,

    instance Monad IO where ...
    

    and >>= for other monads, so don't just blindly apply what you know about one to the other, okay? :)

    instance Monad [] is defined thusly in GHC

    instance Monad [] where
        m >>= k = foldr ((++) . k) [] m
        return x = [x]
        ...
    

    but it is probably easier to understand []'s >>= as

    instance Monad [] where
        m >>= k = concatMap k m
    

    If you take this and apply it to the original, you get

    f1 = concatMap (\x -> [x, x+1]) [1,2]
    f2 = concatMap (\x -> [[x, x+1]]) [1,2]
    

    and it's clear why the values of f1 and f2 are what they are.

提交回复
热议问题