Using return vs. not using return in the list monad

后端 未结 6 670
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

    It's easy to see when re-writing the code with bind and return:

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

    Your first code is tantamount to calling join on the results of the second, removing one monadic "layer" introduced by return :: a -> m a, conflating the "list" of the monad in use, with the "list" of your value. If you were returning a pair, say, it wouldn't have made much sense to omit the return:

                                         -- WRONG: type mismatch
    [1,2] >>= (\x->        (x,x+1)) === concatMap (\x-> (  x,x+1  )) [1,2]
                                         -- OK:
    [1,2] >>= (\x-> return (x,x+1)) === concatMap (\x-> [ (x,x+1) ]) [1,2]
    

    Or, we can use a join/fmap re-write:

    ma >>= famb === join (fmap famb ma)   -- famb :: a -> m b, m ~ []
    
    join (fmap (\x->        [x,x+1]) [1,2]) = concat [ [  x,x+1  ] | x<-[1,2]]
    join (fmap (\x->        (x,x+1)) [1,2]) = concat [ (  x,x+1  ) | x<-[1,2]]  -- WRONG
    join (fmap (\x-> return [x,x+1]) [1,2]) = concat [ [ [x,x+1] ] | x<-[1,2]]
    
                                                             =  [y | x<-[1,2], y<-[ x,x+1 ]]
                                                {- WRONG -}  =  [y | x<-[1,2], y<-( x,x+1 )]
                                                             =  [y | x<-[1,2], y<-[[x,x+1]]]
    

提交回复
热议问题