List もモナド

あどけない話 / QAで学ぶMonadを読んでいます。
fmap は名前からして map の親戚で 関数を List に摘要させるのかと思ったら、違った…Orz

ghci> :m Control.Applicative

ghci> :t map
map :: (a -> b) -> [a] -> [b]

ghci> :t fmap
fmap :: (Functor f) => (a -> b) -> f a -> f b

> map (+1) [1,2,3]                    -- => [2,3,4]
> fmap (+1) [1,2,3]                   -- => [2,3,4]
> fmap (+1) [Just 1, Just 2,Nothing]

<interactive>:1:6:
    No instance for (Num (Maybe t))
      arising from a use of `+' at <interactive>:1:6-7
    Possible fix: add an instance declaration for (Num (Maybe t))
    In the first argument of `fmap', namely `(+ 1)'
    In the expression: fmap (+ 1) [Just 1, Just 2, Nothing]
    In the definition of `it':
        it = fmap (+ 1) [Just 1, Just 2, Nothing]

> map (fmap (+1)) [Just 1, Just 2,Nothing]
   -- => [Just 2,Just 3,Nothing]

List は Myabe、IO のようなモナド

-- (<$> は fmap のシノニム)
--  http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-Functor.html

(<$>) :: (Functor f) => (a -> b) -> f a -> f b

An infix synonym for fmap. 
  • 文脈という言葉を使って <$> を説明すると、<$> は第一引数の関数を文脈に「もちあげる」ための関数。(あどけない話 / QAで学ぶMonad)
ghci>  (+1) <$> [1,2,3]    -- => [2,3,4]
ghci>  (+1) <$> []         -- => []

ghci>  (+1) <$> Just 123   -- => Just 124
ghci>  (+1) <$> Nothing    -- => Nothing

ghci>  (+1) <$> return 123 -- => 124
ghci> (<$) 0 [1,2,3]      -- => [0,0,0]
ghci> (<$) 0 []           -- => []
ghci> (<$) 0 Just 123     -- => 0
ghci> (<$) 0 Nothing      -- => Nothing
ghci> (<$) 0 $ return 123 -- => 0