「Swiftはせっかくマルチパラダイムなのに、この関数型ちっくなところはどこから学んで活用していけばいいのだろう?Haskellとかやったことないんだけど?」
という数ヶ月来の疑問があったので、ここまで学習したことをまとめるついでにとっかかりどころを書いてみようと思います。
なお、「この順番で学ぶとよさそう」というだけの話で、具体的な話は定義含め一切ありません
結論としては
- Optionalの処理を理解する
- 高階関数が何たるかを理解する
- 副作用が何たるかを学ぶ
- Optionalにmapを使う
- ファンクターを理解する
- カリー化して部分適用する
- アプリカティブを理解する
かなというところです。この流れなら無理せず入れるんではないかと…
Optionalの処理について
いわゆる
- Forced Unwrapping
- Optional Chaining
- Optional Binding
- Implicitly Unwrapped Optional
の話。xcodeで試しにSwiftを書いていると、変数やメソッドの後ろに勝手に !
とか ?
とかついて「なんで勝手につくの?」「どんなとき !
で ?
なの?」となったのが懐かしい。いまやぐぐると上記4種の記事はいくらでも出てくるのでそれで学ぶ。
とりあえずSwiftにはnilというのがあって4種の中から正しい方法を選んで処理しなくちゃいけないんだということを学んで次に行く
高階関数について
Swift初学者の人が勉強しているとそのうち変数引数に関数を入れたり、クロージャを使ったりする章に出くわすことになる、The Swift Programming Languageでいうところの
- Functions and Closures(A Swift Tour)
- Functions(Language Guide)
- Closures(Language Guide)
のこと。特に、この中で出てくるmap関数はSwiftを勉強している人にとってのとっかかりになるのでよく練習する。Swiftは関数自体をやったりとったりできるんだなあふむふむと思いながら次に行く
副作用が何たるかを学んで正しくコードを書く
以上まではSwiftを書くにあたって必修だが、ここで「せっかくだから」と関数型プログラミングを始めるとなると心得を学ばないといけなくなってくる、これ以降中途半端にやるとまさかりが痛いので夜道に気をつける
というわけで、ぐぐると副作用がなんたるかとか参照透過性がなんたるかとかあれこれしてはいけないとかというのがでてくるので、それを読む。そうしたら、
-
var
を使わずlet
を使って書く
から始めてみる。そして、Optionalは「中身がnil(空)かもしれない箱」だということをつかんだら次に行く。Optionalは副作用ダメルールに則っているので重要だし、今後出てくる抽象的な概念を理解するときの身近な具体例となる
Optionalにmapを使う
箱だということがわかっても箱からの出し入れの操作がわからないといけないので、定番の map
と flatmap
を使ってあそぶ。まずは map
、慣れたら flatmap
。
参考になりそうな記事:
http://qiita.com/koher/items/68585cff691d87124077
http://qiita.com/koher/items/c6f446bad54442a28bf4
どうも世の中には flatten
関数があってflatmapはmapとflattenを合体させたものという話らしいので、map→flatten→flatmapと辿るといいのではと思うのだが、今の所Swiftにはflattenなるものがあったという話は聞かないしflatmap自体標準装備はSwift2からというオチ
ファンクターを理解する
ひたすら箱と戯れたあとはファンクターに進むことができるのではないかと思う。Optional以外にも"箱"はあるので、あらゆる"箱"に対して通じる話をしていかなくてはいけない。例えばEitherとか。
(自分で実装しないといけない関数や演算子があるとはいえ)この辺りを理解すればdo-try-catchもできてOptionalも使えてEitherも使えるのでエラー処理法の選択肢がぐんと広がる。
カリー化して部分適用する
思う存分"箱"を扱うにはカリー化を学ぶとやれることが増えるので、やっておくといい。
ただし、中途半端な学習をするとカリー化と部分適用の区別がつかなくなって関数型警察に捕まってしまうので、せっかくなら「カリー化を理解する」をゴールにするより「カリー化と部分適用について、両者の違いを明確にした説明ができる」をゴールにしたほうがいい気もする。
アプリカティブファンクターでたくさん箱を扱う
現実には箱を2つも3つも抱えて、それを関数の引数に入れるという事態が起きる。1つならともかく、nil判定を2回も3回もこなしてようやく目的の関数を実行するのはしんどい。そこで、手際よく箱の中身を出して関数に適用して結果を箱に詰めて……という作業をこなすことを可能にする手法を学ぶと役に立つ。
ここまでくれば次の目標はモナドだ!とっても楽しみ!
と言いたいところなのですが、Swift語で書かれた関数型プログラミングの資料は少ない、あってもすでにHaskell語が話せる人向けだったりするので、「やる前に別の言語に手を出さなくちゃいけないのか」となってしんどいです。