[Swift] なにも考えずに使うアプリカティブ

### これはなに？

圏論とか全然意味わかんない僕が出会ったアプリカティブと、僕でも分かったアプリカティブの**利用法**

難しいことはなにも考えずにただアプリカティブを使うことを目的としています。

説明に使うフレームワーク [GitHub: thoughtbot/Runes](https://github.com/thoughtbot/Runes)
記号などはこのフレームワークに準じます。


### これだけは知ってないとダメかも


#### CarthageまたはCocoaPodsまたはSwiftPackegeManager

上に書いた[GitHub: thoughtbot/Runes](https://github.com/thoughtbot/Runes)を使うにはいずれかの知識があったらすごく楽です。

#### カリー化（というか関数を返す関数）

２つの引数を取る関数があります。

```swift
func printN(_ count: Int, _ str: String) -> Void {
  
  for _ in 0..<count {
    
    print(str)
  }
}
```


この関数を引数を一つずつ取るようにしたい。

普通ならこの関数の呼び出しは

```swift
printN(10, "ふつうです")
```

のようになりますが、これを

```swift
printN(10)("ふつうじゃない")
```

のようにしたいということです。

こうなります。

```swift

func printN(_ count: Int) -> (String) -> Void {
  
  func result(str: String) {
    
    for _ in 0..<count {
      
      print(str)
      
    }
  }
  
  return result
}
```

難しく見えるかもしれませんが、はじめにあげた関数と見比べると意味が分かると思います。

複数の引数を取る関数を一つの引数を取る関数に変換することをカリー化と呼びます。
なぜなんでしょうね？　リンゴとはちみつが入ってるんでしょうか？

#### ジェネリクス

モナドとかアプリカティブとかは型をジェネリクスで扱うのが普通です。
ジェネリクスを使うことをカッコよく言うと抽象化とか一般化といいます。いまいちピンと来ませんね。

上の`printN`をジェネリクスを使ったのもに書き換えます。

```swift
func printN<T: CustomStringConvertible>(_ count: Int) -> (T) -> Void {
  
  func result(value: T) {
    
    for _ in 0..<count {
      
      print(value.description)
      
    }
  }
  
  return result
}
```

ジェネリクスのメリットは上の例では二つ目の引数（のように見える返される関数の引数）に大体何でも渡せるようになるということです。

```swift

printN(10)("じぇねりくす")
printN(3)(5)
printN(999)([0, 1, 2])
```
どれも期待通り動きます。


### アプリカティブ

ズバリいきましょう。アプリカティブとはつまりこういうものです。

```swift

f <^> a1 <*> a2
```

はっきり言いましょう。
**意味が分からない**

#### アプリカティブってなに？

変な記号のことをアプリカティブと思いがちですが、アプリカティブは上の例でいうと`a1`と`a2`のことです。
変な記号と一緒に使うことが出来る型をアプリカティブといいます。

以下では、[GitHub: thoughtbot/Runes](https://github.com/thoughtbot/Runes)を使ってOptionalをアプリカティブとして扱います。
[GitHub: thoughtbot/Runes](https://github.com/thoughtbot/Runes)がなんか魔法みたいなことをしてOptionalがアプリカティブになってます。

#### アプリカティブを使うとどうなるの？

先に作った`printN`に渡す値がOptionalであった時のことを考えましょう。

つまりこういう時です。

```swift

let count: Int? = 10
let value: String? = "あぷりかてぃぶ"
```

直接使うことは出来ませんから、何か考えないといけません。
例えばこうでしょうか？

```swift

switch (count, value) {

case let (c?, v?): printN(c)(v)

default: ()
}
```

あるいは、こうでしょうか？

```swift

count.map { c in value.map { v in printN(c)(v) } }
```

いずれも正しく動きますが、読みにくいです。

では、例の変な記号を使ってみましょう。

```swift
printN <^> count <*> value
```

**なんだこれ？ 読みやすい！？**

変な記号を挟んでアプリカティブであるOptionalを`printN`の引数の順番に並べただけで正しく動くのです。

**これこそがアプリカティブの目指すところです。**


#### もっと使ってみよう

`printN`がどうなっていたのかもう一度見てみましょう。

```swift
func printN<T: CustomStringConvertible>(_ count: Int) -> (T) -> Void
```
一つの引数を取って、一つの引数を持つ関数を返す関数でした。

では、この形を守って別の関数を作ってみましょう。
数と何かを受け取ってその数分の何かを要素とするArrayを返す関数を作ります。
引数の順番が逆ですが`Array(repeating:count:)`と同じことをします。

```swift
func makeArray<T>(_ count: Int) -> (T) -> Array<T> {
  func result(_ value: T) -> Array<T> {
    return (0..<cout).map { value }
  }
  return result
}
```

これを`pintN`の代わりに使ってみます。

```swift


let array = makeArray <^> count <*> value
array.map { print($0) }
// prints ["あぷりかてぃぶ", "あぷりかてぃぶ", "あぷりかてぃぶ", "あぷりかてぃぶ", "あぷりかてぃぶ", "あぷりかてぃぶ", "あぷりかてぃぶ", "あぷりかてぃぶ", "あぷりかてぃぶ", "あぷりかてぃぶ"]
```

すばらしい！


ジェネリクスを使ったほうが汎用性が高まりますが、特定の動作であればジェネリクスを使わなくても全く問題ありません。

```swift

func appendString(_ str1: String) -> (String) -> String {
  return { str2 in str1 + str2 }
}

let str1: String? = "アプリカティブ"
let str2: String? = "簡単なのでは？"

let str = appendString <^> str1 <*> str2
str.map { print($0) }
// prints アプリカティブ簡単なのでは？
```

**アプリカティブ簡単なのでは？**

#### もう一つの変な記号

アプリカティブに対して使えるもう一種類の変な記号があります。これを見てみましょう。

##### 順番と結果

次のような関数を作ることを考えます。

> 2つのOptionalを返す関数があり、これらを順番通りに呼び出します。
> 1つ目の関数がnilを返したら2つ目の関数は呼び出さずnilを返します。
> 結果として1つ目の関数が返す値を返します。

まずは普通に書いてみましょう。

```swift

func getFirstValue() -> String?
func getSecondValue() -> String?

func getValue() -> String? {
  
  guard let firstValue = getFirstValue() else { return nil }
  
  _ = getSecondValue()

  return firstValue
}
```

簡単でしたね。ではこれを変な記号その2を使って書いてみましょう。

```swift

func getFirstValue() -> String?
func getSecondValue() -> String?

func getValue() -> String? {

  return getFirstValue() <* getSecondValue()
}
```
**1行！！**

使う値を2つ目の関数の値とする場合は普通の書き方では

```swift

func getValue() -> String? {
  
  guard let _ = getFirstValue() else { return nil }
  
  return getSecondValue()
}
```

アプリカティブなら

```swift

func getValue() -> String? {

  return getFirstValue() *> getSecondValue()
}
```

**やっぱり1行！**

`<*`、`*>`の向きが利用する値であると見るとすごく分かりやすいですね。

ここまで単純化されるとわざわざ関数を作る必要すらなくなってしまいます。
この関数化する必要がなくなる事もアプリカティブを利用するメリットです。

#### アプリカティブ

変な記号はSwiftではカスタムオペレータとして定義されています。
この内容を理解するのはとても大変です。

でも、使うだけなら今すぐ誰にでも使えます。

[GitHub: thoughtbot/Runes](https://github.com/thoughtbot/Runes)ではOptionalだけでなくArrayもアプリカティブとして使える魔法がかかっています。

みなさんもなにも考えずにアプリカティブを使ってみましょう。


### おまけ

#### ファンクタの変な記号

先の例をもう一度見てみます。

```swift

let str = appendString <^> str1 <*> str2
str.map { print($0) }
```

最後の一行が何か残念です。
変な記号を作って残念さを取り除きます。

```swift
// 簡単にするため RunesApplicativePrecedence を借用
infix operator <&> : RunesApplicativePrecedence 

func <&> <T, U>(lhs: Optional<T>, rhs: (T) -> U) -> Optional<U> {
  
  return lhs.map(rhs)
}
```
Optionalのmap関数をオペレータにしただけです。

この変な記号を使うと次のように書けます。

```swift

appendString <^> str1 <*> str2 <&> { print($0) }
```

見やすくなりました。

#### オルタナティブ

アプリカティブとは別にオルタナティブと呼ばれるものもあります。
なぜ呼び名が違うのかは偉い人に考えてもらって僕たちはおいしくいただくだけにしましょう。

```swift
let left: String? = nil
let right: String? = "OK"

left <|> rigt <&> { print($0) }
// prints OK

let left2: String? = "OOOKKKKKK!!!!"

left2 <|> right <&> { print($0) }
// prints OOOKKKKKK!!!!
```
これは見たらすぐ分かりますね。 左がダメなら右、です。

#### ほかにも

他にもいろいろ変な記号があったり面白い使い方があったりします。
興味があったら調べて見てもいいかもしれません。