「すごいHaskell たのしく学ぼう!」を読んだ
- 作者: Miran Lipovaca
- 出版社/メーカー: オーム社
- 発売日: 2012/09/21
- メディア: Kindle版
- 購入: 4人 クリック: 9回
- この商品を含むブログを見る
本書は一度は8章あたりで挫折したが、今回13章あたりまで読みファンクタ―、アプリカティブファンクタ―、モノイド、モナドといった概念がなんなのか理解とまでは言えないけど知ることができた。
一度は挫折したが今回またリベンジしようと思った理由は、今後モバイルアプリを開発していくにあたって関数型プログラミングの概念を理解して採り入れていくことが必要になってくると思ったからだ。Swiftはlet
による不変型の宣言やOptional
型などの文脈付きの型など関数型プログラミング言語としての側面をもっていると思う。また、データバインディング(SwiftBond/Bondなど)やJSONのパース(thoughtbot/Argoなど)といった場面で関数型プログラミングの概念が登場してきている。Swiftのポテンシャルを最大限に発揮して、堅牢で生産性の高いコードを書くには関数型プログラミングの知識が必要になってきていると最近感じている。
本書を読んだ結果として、データの構造について新しい視点を得ることができた。Maybe
やEither
といった概念を"文脈"と呼んでいるのが自分の中にはなかった発想だった。例えば、Maybe
とMaybe Int
を区別して考えるのはとても抽象的だけど強力な考え方と思った。Maybe
は「あるかもしれないし、ないかもしれない」という文脈を表し、Maybe Int
は「Int
型かもしれないし、何もないかもしれない」型を表している。これらを分けることで、文脈を保ったまま計算するという発想が出てくるのだと思う。文脈を保ったまま計算する段階として、本書ではFunctor
やApplicative
、そしてMonad
が登場してきた。
Swiftでは、Haskellにおける型コンストラクタにあたる概念がない。Genericsを使うことでMaybe
のような型を表現することはできるが、ある型が型引数をとるのかとらないのか、とるとしたらいくつとるのかを知る術はない(はず)。Haskellではそれらは種類という概念で説明されている。Maybe
の種類はMaybe :: * -> *
だし、Either
の種類はEither: * -> * -> *
となっているので、それぞれ型引数を1つと2つとることがわかる。HaskellのFunctor
は種類が* -> *
の型コンストラクタしかインスタンスにできないのだけど、こういう概念をSwiftで表現できない。
というわけで、Swiftで関数型プログラミングをするにはHaskellほどうまくはできないことがなんとなくわかった。Genericsなどで擬似的に表現するしかない。Functor
のfmap
を以下のように実装してみた。
extension Optional {
func fmap<U>(f: T -> U) -> U? {
switch self {
case .Some(let value):
return f(value)
case .None:
return .None
}
}
}
let maybeOne: Int? = 1
let maybeTen = maybeOne.fmap({ x in x * 10 })
SwiftのOptional<T>
型はつまりT?
型のことなのだけど、Optional
型を拡張してfmap
を追加している。return f(value)
のところは暗黙的にU?
型にラップしている。このように実装することで、Optional
型のもつ「あるかもしれないし、ないかもしれない」という文脈を保ちつつ、中身の1
というInt
を計算している。
ここではFunctor
だけを簡単に実装してみたが、これに加えてApplicative
とMonad
を実装するとより抽象的な計算が可能になってくる。JSONのパースなどを実装する際にはApplicative
の操作が必要になってきそうな感じがする。自分はまだ関数型プログラミングの実装を実際にしたわけではないので、理解したとは到底いえない。パーサーの実装をしてみたり、上で紹介したライブラリのコードを読んでみることで関数型プログラミングを実践的に理解していきたい。