Monad入門以前: (Functor,Applicative)

Haskellを学ぶに当たって避けて通れないのがMonadですね(?)
しかしいきなりMonadを理解するのは難しいかと思います.

なので, まずFunctorとApplicativeを理解してみようというお話です.

# FunctorとApplicativeがどうMonadと繋がるのか
モナドの定義をみてみましょう

```haskell
class Applicative m => Monad (m :: * -> *) where
  (>>=) :: m a -> (a -> m b) -> m b
  (>>) :: m a -> m b -> m b
  return :: a -> m a
  fail :: String -> m a
```

またApplicativeの定義をみてみましょう

```haskell
class (Functor f) => Applicative f where
  pure :: a -> f a
  (<*>) :: f (a -> b) -> f a -> f b
```

となっています.
Monad構造を持つものはApplicative構造を持っています.
またApplicative構造を持つものはFunctor構造を持っています.
`Functor => Applicative => Monad`
よってMonadを学ぶにはFunctorとApplicativeを理解する必要があると思います.

# Functor

## Functorとは？
Functorとは`全体を写せる(map over)ものの型クラス`です.
よくわかりませんね.
一つ例をあげるとリストはFunctorに属します.
リストのメソッドに`map`というメソッドがあります. よく使われますね.
Swiftでの例をみてみましょう.

```swift
func double(x: Int) -> Int {
    return x * 2
}
let x = [1,2,3]
let y = x.map(double) // [2,4,6]
```
mapはどのような動きをしているかというと, xの要素である1,2,3に対して`double`を適用し, リストに包んで返しています.
つまり, この例では
全体: `リストに包む`
写す: `doubleを適用`
と対応が取れます.
これらからFunctorは`元の構造を保ったまま, 関数が適用できるような構造`のことを指します.

## Functorの実装を見る
HaskellのFunctor型クラスを見てみましょう.実装は以下のようになっています

```haskell
class Functor f where
  fmap :: (a -> b) -> f a -> f b
```

これだけです.それではfmapを詳しくみてみましょう.
fmapの第一引数は(a型の値をとってb型の値を返す関数)です.特に問題はないですね.
第二引数は(f a)となっています. 
これはfという構造を持ったa型の値を表しています. リストで言えば`f a = [] a = [a]`です.

結局のところ, fmapは何をするのかというと
`fという構造を持ったもの(fはa型の値を持つ)に対して何か関数を適用して, fという構造を保ったまま返す`
ということをしています.

## Optional（Maybe）を実装してみる
さて、上で説明したことをOptional(Maybe)を使って実装してみます.
HaskellとSwiftの二つの言語で実装しました.

### Haskell

まずデータ型を定義します.
値を持っていればSomeで値をラップし, 値がない場合はNoneとします.

```haskell
data Optional a = Some a | None deriving (Eq, Ord, Read, Show)
```

OptionalはFunctorを準拠します.
Optionalが値を持っている(Some)ならば, Someの中の値に関数を適用して, 再度Someでラップします.
値を持っていない(None)ならば, Noneを返します. (何もないものに関数を適用しても何も起こりませんよね)

```haskell
instance Functor Optional where
  fmap f (Some x) = Some (f x)
  fmap f None     = None
```

さて確かめてみましょう.

```
*Main> x = Some 10
*Main> y = None
*Main> fmap (*2) x
Some 20
*Main> fmap (*2) y
None
```
うまく動いていますね.

### Swift
SwiftではFunctor自体を定義します.

```swift
protocol Functor {
    associatedtype A
    associatedtype B
    associatedtype F
    func fmap(f: ((A) -> B)) -> F
}
```

次にOptionalを定義します.(名前が衝突するのでMyOptionalとしています)
また, MyOptional(T)に対してMyOptional(U)を返す方法がわからなかったので今回は同じ型を返すようにしています(MyOptional(T)に対してMyOptional(T)を返すようにしています)

```swift
enum MyOptional<T>: Functor {
    typealias A = T
    typealias B = T
    typealias F = MyOptional
    
    case some(value: T)
    case none
    
    func fmap(f: ((T) -> T)) -> F {
        switch self {
        case .some(let value):
            return .some(value: f(value))
        case .none:
            return .none
        }
    }
}
```

さて確かめてみましょう.

```swift
let x = MyOptional<Int>.some(value: 1)
let y = MyOptional<Int>.none
let z = x.fmap(f: { x in return x * 2 })
let w = y.fmap(f: { x in return x * 2 })
print(x)  // some(value: 1)
print(y)  // none
print(z)  // some(value: 2)
print(w)  // none
```
うまく動いています.


# Applicative
## Applicativeとは
先ほど`fmap (*2) (Some 1)`をFunctorの利用例としてあげました.
実は`fmap (*) (Some 2)`もできます.
この型は`fmap (*) (Some 2) :: Num a => Optional (a -> a)`となっています.
書き方を変えると`Some (2 *)`です. つまり, Functor値に関数を与えることもできます.

ではこれを踏まえて, `Some (2 *)`と　`Some 3`があったとして,　`Some (2 *)`を`Some 3`に適用できるでしょうか. 答えはNoです. 
残念ながらFunctorだけの世界では, `Some (2 *)`は使い物になりません.

ここでApplicativeが登場します.
Applicativeな世界では`Some (2 *)`を`Some 3`に適用することができます.
つまり, `(Some (2 *)) (Some 3) = Some 6`を得ることができる世界になるわけです.

## Applicativeの実装をみる
HaskellのApplicative型クラスを見てみましょう.実装は以下のようになっています

```haskell
class (Functor f) => Applicative f where
  pure :: a -> f a
  (<*>) :: f (a -> b) -> f a -> f b
```

詳しくみていきましょう.
まず1行目`class (Functor f) => Applicative f`について,「Applicativeな`f`はFunctor型クラスを準拠している必要がある.」という制約をつけています.
二行目以降は「Applicativeな`f`は`pure`と`<*>`の実装を持つ必要がある」と言っています.
`pure`は「ある値をfで包む, つまりApplicative値に変換する関数」,
`<*>`は「fで包まれた（a->b）な関数を,fに包まれたa型の値に対して適用してfに包まれたbを返す」
となっています.

## Optional(Maybe)を実装する
Functorの説明で実装したOptionalにApplicativeを準拠させます.

### haskell

```haskell
instance Applicative Optional where
  pure = Some
  None <*> _ = None
  (Some f) <*> x = fmap f x
```

`pure`はSomeで包みます. `pure (*2)`とすると, `(Some (*2))`が得られます.
`<*>`は　(Optional 関数) <*> (Optional 値)のように使います.
左引数(関数)がNoneの場合, 問答無用でNoneを返します.何かに<b>無</b>を適用しても<b>無</b>です.
左引数(関数)がSomeの場合, Some内の関数を取り出し, fmapを適用します.　つまり両辺のSomeから値を取り出し, 適用しSomeに入れて返すということをしています.

確認してみましょう

```haskell
*Main> Some (+3) <*> Some 2
Some 5
*Main> pure (*2) <*> Some 10
Some 20
*Main> pure (*2) <*> None
None

-- アプリカティブスタイル <*> を連続して使う
*Main> pure (+) <*> Some 3 <*> Some 5
Some 8
*Main> pure (+) <*> Some 3 <*> None
None
*Main> pure (+) <*> None <*> Some 5
None
```

### Swift

Swiftでの実装は以下のようになります

Applicative型クラスを実装したいところでしたが, どうしたらいいかわからなかったのでMyOptionalをextensionしてpureと<*>を実装します. <*>はapplyとして実装します

```swift
extension MyOptional {
    static func pure<U>(_ a: U) -> MyOptional<U> {
        return .some(value: a)
    }
    
    func apply(_ f: MyOptional<((T) -> T)>) -> MyOptional<T> {
        switch f {
        case .none:
            return .none
        case .some(let fun):
            return self.fmap(f: fun)
        }
    }
}
```

確認してみましょう.

```swift
let f1 = MyOptional<Int>.pure({ x in x+2 })
let f2 = MyOptional<Int>.pure({ x in x*3 })
let x = MyOptional<Int>.some(value: 2)
let y = x.apply(f1).apply(f2)
print(x) // some(value: 2)
print(y) // some(value: 12)
```

うまくいっているように見えます.
しかし残念ながら, swiftでCurry化は普通には使えないのでアプリカティブスタイルはかけませんでした.
Curry化を実装すれば,　できそうです.

それは辛いので今回は実装しません.

# あとがき
Haskellを書き始めて二ヶ月程度なので, 変なことを言っている可能性があります.
そういったところはマサカリを投げていただけると助かります.


# 参考文献
すごいHaskell楽しく学ぼう!