箱で考えるFunctor、ApplicativeそしてMonad


モナドについて勉強していて見つけた英語記事を翻訳してみました。
誤訳等あれば編集リクエストやコメントください :bow:

原文: [Functors, Applicatives, And Monads In Pictures - adit.io](http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html)

------------

ここに単純な値(value)があります。

![value.png]

```haskell
Prelude> 2
2
```

そして、私たちはこの値に関数を適用する方法を知っています。

![value_apply.png]

```haskell
Prelude> (+3) 2
5
```

とても簡単ですね。それでは、ある状態(context)に値が入っていると仮定してみましょう。これからみなさんは値を入れられる状態のことを、箱だと考えてもらって構いません。

![value_and_context.png]

```haskell
Prelude> Just 2
Just 2
```

そして、この値に関数を適用したとき、 **状態によって** 異なる結果が返ります。この考え方に、Functor、Applicative、Monad、Arrowなどがもとづいています。`Maybe` データ型は2つの状態を定義できます。

![context.png]

```haskell
data Maybe a = Nothing | Just a
```

```haskell
Prelude> :type Just
Just :: a -> Maybe a

Prelude> :type Nothing
Nothing :: Maybe a
```

次に、`Just a` と `Nothing` それぞれに関数を適用したときどのような違いが出るか見てみましょう。先に Functor について話してみようと思います。

# Functor

箱に入っている値に対して、普通の関数を適用することはできません。

![no_fmap_ouch.png]

```haskell
Prelude> (+3) (Just 2)
 ERR - No instance for (Num (Maybe a0))
```

ここで `fmap` が登場します。`fmap`はその道の出身で、状態についてよく知っています。`fmap` は箱に入っている値にどのような関数を適用しなければならないか分かっています。例えば、 `Just 2` に `(+3)` を適用してみましょう。 `fmap` を使ってみると…

```haskell
> fmap (+3) (Just 2)
Just 5
```

![fmap_apply.png]

__ポン!__ `fmap` がやってくれました。では、どのように `fmap` は関数を適用する方法を知っていたのでしょうか?

# Functorとは一体何だろうか?

`Functor` は [typeclass] です。ここにその定義があります:

![functor_def.png]

 
`Functor` は fmap を適用する方法を定義したデータ型です。ここにどのように fmap が動作するのかが出ています。

![fmap_def.png]

したがって、私たちは次のようにすることができます。

```haskell
> fmap (+3) (Just 2)
Just 5
```

そして `Maybe` もまた `Functor` なので、`fmap` は魔法のように関数を適用してくれました。どのように `fmap` が `Just` と `Nothing` に適用されるかについてが次に出ています。

```haskell
instance Functor Maybe where  
    fmap func (Just val) = Just (func val)
    fmap func Nothing = Nothing 
```

ここに `fmap (+3) (Just 2)` と打ったとき、裏でどんなことが起こるかが現れています。
 
![fmap_just.png]

それでは、 `(+3)` を `Nothing` に適用してみてください。

![fmap_nothing.png]

```haskell
> fmap (+3) Nothing
Nothing
```

![bill.png]

_Maybe functorも知らないBill O'Reilly_

マトリックスのモーフィアスのように、`fmap` は何をしなければならないか知っています。 `Nothing` で始まり、`Nothing` で終わる! `fmap` は禅です。では、`Maybe` データ型がなぜ存在するのか考えてみましょう。例えば、 `Maybe` がない言語で、データベースのレコードを扱おうとしたらこうなります。

```ruby
post = Post.find_by_id(1)
if post
  return post.title
else
  return nil
end
```

しかし、Haskellは次のようにできます。

```hakskell
fmap (getPostTitle) (findPost 1)
```

もしも、`findPost` が投稿(post)を返すならば、`getPostTitle`でタイトルを得ることができます。 `Nothing` を返したら、`Nothing` を得るのです。とっても簡単じゃないですか? `fmap` の周囲表記(infix) バージョンは `<$>` で、次のように書くこともできます。

```haskell
getPostTitle <$> (findPost 1)
```

ここにもう一つの例があります。リストに関数を適用したらどんなことが起こるでしょうか?

![fmap_list.png]

リストもやはり functor だったのです! ここにその定義があります。

```haskell
instance Functor [] where
    fmap = map
```

ではでは、最後にもう一つ例を。関数にまた別の関数を適用しようとしたらどんなことがおこるでしょうか?

```haskell
fmap (+3) (+1)
```

```haskell
Prelude> :type fmap (+3) (+1)
fmap (+3) (+1) :: (Functor ((->) b), Num b) => b -> b
```

ここにある関数があります。

![function_with_value.png]


関数にまた別の関数を適用してみようと思います。

![fmap_function.png]

結果もやはり関数でした。

```haskell
> import Control.Applicative
> let foo = fmap (+3) (+2)
> foo 10
15
```

したがって、関数も Functor なのです。

```haskell
instance Functor ((->) r) where  
    fmap f g = f . g
```

関数に fmap を使用すると、関数の合成(function composition)をしたのと同じです。



# Applicative

次の段階のApplicativeに進んでみましょう。Functorでやってみたように、箱に値を入れます。

![value_and_context.png]


そして、関数もまた箱に入れられるのです!

![function_and_context.png]

はい、じゃあ詳しく見てみましょう。Applicativeもバカじゃありません。`Control.Applicative` は `<*>`  を定義していて、 **箱の中の** 値に、 **箱の中の** 関数を適用する方法を知っています。

![applicative_just.png]

なので、次のようなことができます。

```haskell
Just (+3) <*> Just 2 == Just 5
```

`<*>` を使うと少し面白い結果を得ることができます。例えばこんな。

```haskell
> [(*2), (+3)] <*> [1, 2, 3]
[2, 4, 6, 4, 5, 6]
```

![applicative_list.png]


ここでFunctorにはできなかったけど、Applicativeにはできることが出てきます。どうやって、中に値が入ってる2つの箱に、2つの引数を取る関数を適用するのでしょうか?

```haskell
> (+) <$> (Just 5)
Just (+5)
> Just (+5) <$> (Just 4)
ERROR ??? WHAT DOES THIS EVEN MEAN WHY IS THE FUNCTION WRAPPED IN A JUST
```







































Applicativeなら:

```haskell
> (+) <$> (Just 5)
Just (+5)
> Just (+5) <*> (Just 3)
Just 8
```

`Functor` を横に追いやりながら `Applicative` は言います。

「大物は引数をいくつ取る関数だって扱えるんだぜ?」
  
「`<$>` と `<*>` を使ってオレは、箱を開いてみることができない関数どもに、箱の中の値を渡してやって、しまいに値を箱にいれて返すこともできるのさ! ぷははは!」


```haskell
> (*) <$> Just 5 <*> Just 3
Just 15
```

![TaTdV.gif]

_functorが関数を適用するのを見ていたapplicative_

でもちょっと待って! ここに同じことをする `liftA2` もいます。

```haskell
> liftA2 (*) (Just 5) (Just 3)
Just 15
```

# Monad

モナドを学ぶ方法:

1. 情報工学の博士号を取る
2. ここでは博士号は要らないので取らない

モナドは新しい解法を提示しました。
 
Functorは箱に入っている値に関数を適用できます。

![fmap.png]

Applicativeは箱に入っている値に、箱に入っている関数を適用できます。

![applicative.png]

モナドは箱に入っている値に、 **箱に入った値を返す** 関数を適用できます。

モナドはこのようなことをする("bind"と呼ばれる) `>>=` という関数を持っています。

例を見てみましょう。これまでに見てきた `Maybe` はモナドです。

![context.png]

_遊んでたJust aモナド_

偶数に対してだけ動作する関数、`half`があると仮定してみましょう。

```haskell
half x = if even x
           then Just (x `div` 2)
           else Nothing
```

![half.png]

値が入っている箱を入れてみるとどうなるでしょうか?

![half_ouch.png]

関数に値が入っている箱を押し込めたいなら、`>>=` が必要です。ここに `>>=` の写真があります。

![plunger.jpg]

どんなふうに動作するのか確認してみましょう。
 
```haskell
> Just 3 >>= half
Nothing
> Just 4 >>= half
Just 2
> Nothing >>= half
Nothing
```

内部でどんなことが起こっているのでしょうか? `Monad`はまた別の[typeclass]です。ここに定義の一部が載っています。

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

`>>=`は、

![bind_def.png]

したがって、`Maybe`はモナドです。

```haskell
instance Monad Maybe where
    Nothing >>= func = Nothing
    Just val >>= func  = func val
```


ここに `Just 3` についてどうやって動作しているか載っています!

![monad_just.png]

`Nothing` を入れるともっと単純になります。

![monad_nothing.png]

このようにチェーン(chain)で呼び出すこともできます。

```haskell
> Just 20 >>= half >>= half >>= half
Nothing
```

![monad_chain.png]

![whoa.png]


カッチョイイです。もう私たちは `Maybe` が `Functor` であり、`Applicative` であり、`Monad` であることが分かりました。

それではそろそろ、`IO`モナドの例に行ってみましょう。

![io.png]

> 訳注: 数字の10ではなく、英語のIO

3つの特別な関数があります。 `getLine` は引数を取らず、ユーザの入力を受け取ります。

![getLine.png]

```haskell
getLine :: IO String
```

`readFile` は文字列(ファイル名)を受け取り、ファイルの中身を返します。
 
![readFile.png]

```haskell
readFile :: FilePath -> IO String
```

`putStrLn` は文字列を受け取り出力します。

![putStrLn.png]

```haskell
putStrLn :: String -> IO ()
```

ここに出てきた3つの関数は普通の値を受け取り(または何も受け取らず)、値が入っている箱を返します。したがって、私たちはこれを `>>=` でつなぐことができます。

![monad_io.png]

```haskell
getLine >>= readFile >>= putStrLn
```

なんということでしょう! モナドのショーが巻き起こりました!

付け加えると、Haskellはこのモナドについて、`do` というシュガーシンタクスを提供してくれています。

```haskell
foo = do
    filename <- getLine
    contents <- readFile filename
    putStrLn contents
```

# まとめ

1. functorは `Functor` 型クラスを実装したデータ型。
2. applicativeは `Applicative` 型クラスを実装したデータ型。
3. モナドは `Monad` 型クラスを実装したデータ型。
4. `Maybe` はこの3つをすべて実装しており、functorでありapplicativeでありモナドでもある。

この3つの違いは何か?

![recap.png]

* functor: `fmap` や `<$>` を使って、箱の中の値に関数を適用できる
* applicative: `liftA` や `<*>` を使って、箱のなかの関数を箱の中の値に適用できる
* モナド: `liftM` や `>>=` を使って、箱に入った値を返す関数を箱の中の値に適用できる


わたしたちはみんな、モナドというものが簡単で粋な概念だということについて、同意することと思います。このガイドで満足するのはまだ早いです。[LYAH’s section on Monads]をチェックしてみてください。Miranがすでにモナドに関する深く素晴らしい働きをしているので、だいぶざっくり説明してきました。

 [ロシア語バージョン](http://habrahabr.ru/post/183150/)もあります。もっとモナドと絵を見たい方は [three useful monads]を見てみてください。

> 訳注: [韓国語版](https://github.com/netpyoung/netpyoung.Notes/tree/master/external/haskell/functors_applicatives_and_monads_in_pictures)、[中国語版](http://jiyinyiyong.github.io/monads-in-pictures/)もあります。



[applicative_just.png]: https://qiita-image-store.s3.amazonaws.com/0/889/35f914f4-56ab-1886-54ac-ac1c9140c6d1.png
[applicative_list.png]: https://qiita-image-store.s3.amazonaws.com/0/889/ccb74a3b-510c-26bf-5cb2-f3b70a709a25.png
[applicative.png]: https://qiita-image-store.s3.amazonaws.com/0/889/a2f405ee-921d-fe04-7e20-520e2a3f94c4.png
[bill.png]: https://qiita-image-store.s3.amazonaws.com/0/889/5f588ef0-c059-60c1-30ec-b130677d56ee.png
[bind_def.png]: https://qiita-image-store.s3.amazonaws.com/0/889/da5452e0-306c-4b0b-2cb5-cab6b1face03.png
[context.png]: https://qiita-image-store.s3.amazonaws.com/0/889/08655d17-653d-0970-ad5f-17f284e6b94e.png
[fmap_apply.png]: https://qiita-image-store.s3.amazonaws.com/0/889/5ccd102b-091c-2eec-51d5-f27b3af08299.png
[fmap_def.png]: https://qiita-image-store.s3.amazonaws.com/0/889/5f652556-4e92-b40d-058f-5fdcf7745361.png
[fmap_function.png]: https://qiita-image-store.s3.amazonaws.com/0/889/9e661dfa-9bff-5a69-567e-414173d192d1.png
[fmap_just.png]: https://qiita-image-store.s3.amazonaws.com/0/889/0619238e-831d-c62a-d1fc-cb221873c906.png
[fmap_list.png]: https://qiita-image-store.s3.amazonaws.com/0/889/c1bd7404-87e8-6d02-8783-ba2ddc6eccc8.png
[fmap_nothing.png]: https://qiita-image-store.s3.amazonaws.com/0/889/371d95b1-e307-0b32-69bc-d167fdb7d58e.png
[fmap.png]: https://qiita-image-store.s3.amazonaws.com/0/889/f8c8ccd7-8e4c-d183-f1eb-c5eaec1411da.png
[function_and_context.png]: https://qiita-image-store.s3.amazonaws.com/0/889/ee849c4c-9808-2433-21ad-954975583e5c.png
[function_with_value.png]: https://qiita-image-store.s3.amazonaws.com/0/889/57fdb86f-d720-20a2-42a7-6d03ac59a3f2.png
[functor_def.png]: https://qiita-image-store.s3.amazonaws.com/0/889/ae77308c-fc46-831a-657e-0e8dc73130f2.png
[getLine.png]: https://qiita-image-store.s3.amazonaws.com/0/889/7d4a4b1d-93d0-7b4c-9b68-4dcb73593737.png
[half_ouch.png]: https://qiita-image-store.s3.amazonaws.com/0/889/93a3be8d-da9b-8831-2eb3-5844de13c703.png
[half.png]: https://qiita-image-store.s3.amazonaws.com/0/889/29ec2195-592c-992b-5e78-6114e000cb23.png
[io.png]: https://qiita-image-store.s3.amazonaws.com/0/889/4288a533-09fa-c3d2-b63b-a9ee1e4c5dcb.png
[monad_chain.png]: https://qiita-image-store.s3.amazonaws.com/0/889/65a8d729-7b44-91b4-532d-715bcea5b87e.png
[monad_io.png]: https://qiita-image-store.s3.amazonaws.com/0/889/dba34d28-5e39-af76-2005-f563a6e31102.png
[monad_just.png]: https://qiita-image-store.s3.amazonaws.com/0/889/7371afcc-a3be-aced-9178-5d6939389a57.png
[monad_nothing.png]: https://qiita-image-store.s3.amazonaws.com/0/889/b773a289-b2e9-38a5-47b5-e85568990b6f.png
[no_fmap_ouch.png]: https://qiita-image-store.s3.amazonaws.com/0/889/6a9b961e-8cec-8451-bb4f-139691f657e8.png
[plunger.jpg]: https://qiita-image-store.s3.amazonaws.com/0/889/e4c6d1f0-d900-acd9-eef6-6842e504868b.jpeg
[putStrLn.png]: https://qiita-image-store.s3.amazonaws.com/0/889/e669ea2e-c8c4-2e35-0360-0199f36eba1d.png
[readFile.png]: https://qiita-image-store.s3.amazonaws.com/0/889/d07d4397-70f0-b91a-af45-b7d34585ebe3.png
[recap.png]: https://qiita-image-store.s3.amazonaws.com/0/889/8eda652f-189f-2d22-ca3f-cc90e6e7737d.png
[TaTdV.gif]: https://qiita-image-store.s3.amazonaws.com/0/889/188d4be3-36f0-f990-d87c-ef7b404556ce.gif
[value_and_context.png]: https://qiita-image-store.s3.amazonaws.com/0/889/e08fabf4-8abc-95a8-dc28-30e762ee29f8.png
[value_apply.png]: https://qiita-image-store.s3.amazonaws.com/0/889/b0a88333-3794-e575-89b8-7d683d5b3d36.png
[value.png]: https://qiita-image-store.s3.amazonaws.com/0/889/82c3dfde-98f4-f137-8457-34fbb532b11d.png
[whoa.png]: https://qiita-image-store.s3.amazonaws.com/0/889/99e38ffb-1d72-ab05-32e8-9482baa30993.png




 [typeclass]: http://learnyouahaskell.com/types-and-typeclasses#typeclasses-101
 [function composition]:  http://en.wikipedia.org/wiki/Function_composition
 
 [three useful monads]: http://adit.io/posts/2013-06-10-three-useful-monads.html
 [LYAH’s section on Monads]: http://learnyouahaskell.com/a-fistful-of-monads