Dev日記

プログラミング学習のまとめなど

【書評】関数プログラミング実践入門

関数プログラミング実践入門

1年ちょっと前に買ったものですが、読み直しのついでにレビューをしてみます。

※残念ながら改訂版ではありません..もちろん個人の主観に基づくレビューですので、そこはご了承ください。

購入動機

  • SwiftやScala/Java8等、関数型の側面が入った言語を触ることが多くなった
  • それに伴い、関数型の知識が欲しかった。より関数型らしく組むには が欲しかった知識
  • 特定の関数型言語の知識は求めていない
  • 上記理由により、汎用的に関数型の知識を扱っていそうなこの本を選定

TL;DR

  • 全体的に

    • 思ったよりHaskell入門本だがやや内容が少ない
    • 6章の数独が見どころ
  • 長所

    • Haskell含む、関数型言語に本格的に興味を持てた (後のelmに繋がる)
    • 6章の「関数型らしい設計方法」は非常にためになった
  • 短所

    • 他言語との実装比較が冗長に感じられた(1章)
    • 各種サンプルが、関数型であるメリットをもっと感じる内容だとより良かった

レビュー

思ったよりHaskellの本だった、というのが正直なところです。タイトルから期待する内容と実際の内容にかなりのズレがあります(個人的印象ですけど)。タイトルが「Haskell実践入門」だったらまた違ったでしょう。(買わなかった可能性は大きいですが)

タイトルに沿った内容らしいのは、

  • 「型付け」などプログラミング全般の話題に触れる0章
  • 関数型らしい設計手法を提示した6章

ぐらいでしょうか?


とはいえ実はこの0章が最も関数型のメリットを解説しているのではないかと思います。

関数型言語の特徴、参照透過性と並行処理の相性の良さ、テストのしやすさなどなど関数型のメリットが分かりやすく提示されています。(関数型言語の、というよりHaskellの、というべきかも)

また、6章も「数独」という入門本にしてはかなり複雑な題材を取りあつかい、どのように設計していくかが述べられておりここも面白かったです。

この手の入門書としては相当高難度な題材といえるのではないでしょうか?しかももろに「アルゴリズム」の話で関数型とも相性がいいです。DBやHTTPが不要な分、完全にロジックに集中できます。

ここは本当に見ごたえがありました。ソースコードも豊富で当時は初Haskellでしたがなんとかなりました。


一方で 残りの章は普通のHaskell解説本です

特に1章が厳しい。いくつかのよくある実装パターンでHaskellとの比較を行っているのですが、「相手言語の苦手な分野と比較している」のは残念な印象でした。

たとえば

  • Rubyには型がないから型のあるHaskellいいでしょ?

    • 前のページで取り扱ってたJavaには型あるんだけど…
  • CだとTuple返せないから複数の値を返したい時不便でしょ?

    • 次のページのJSならできるのでは…? いや、Cこそやりたい放題な気が。

というイメージ。Haskellの優位性をよく分からない理由付けで解説してるだけに感じてしまいました。


残りの章は主にHaskellの文法解説+αです。

Haskell入門書としては「FunctorやApplicativeなど厄介な部分を除き」良書という印象。

翻訳書籍でないので変な日本語に悩まされることもありませんし、各単語の説明もきっちりしてて読みやすいです。

問題はそのへんのつまづきやすい部分をさらっと流してること

この説明だけでIOモナドを扱える人はほぼいないのではなかろうか…? その辺は他の書籍で補完しないと厳しいです。

数独のためのHaskell解説」と割り切ってる感はあります。確かに数独ではモナドを意識して使わないので数独部分を理解するには十分ではありました。(List/Maybeは他言語にもあり、モナドと意識せず扱えるから困らない)


ちょっと厳しい感想になってしまいましたが、読んでよかったと思ったのは間違いありません。これを読んでいなかったらelmは理解できなかった、触ろうとも思わなかったはずです。

ただしHaskell入門としては明らかに足りていません。特にモナド周り。ここは注意してください。

しかし6章の数独はそれをひっくり返すぐらい面白かった。先ほども述べたとおり、1-5章はこのための準備と割り切る必要はあると思います。

こういう内容が豊富でもっと具体的な設計手法を見れたら/試せたらより良かったと思います。


この数独を経験することでかなりオブジェクト指向での組み方が変わりました。具体的には「参照透過性のあるメソッド」「ないメソッド」を分離したくなる癖が付きました。(参照透過性のあるstaticメソッドがすごい増えた)

Androidでの簡単な例だと以下のようなイメージです。

//before
if (state.isActive && !state.isLoading) {
  button.setText("送信");
} else {
  button.setText("通信中");
}


//after
static String getButtonText(State state) {
    return (state.isActive && !state.isLoading) ? "送信" : "通信中";
}
String text = getButtonText(state); //なぜか一旦変数に格納したくなる症状も出た
button.setText(text);

とにかくsetTextは1箇所に限定したくなる癖がつきました

コードとしては若干面倒になってますが、副作用を伴う操作は極力減らしたい思考に変わりました。


冗長な面やHaskell入門として足りない面はありますが、このような考え方をかえるきっかけとなった本なので良かったです。

特にelmにつながったのは大きい。(少なくともこの本で得た知識おかげである程度なんとかなったのは事実)

ターゲットとする読者層は狭い気はしますけど、上記のような考えかたに触れてみたいのでしたらオススメです。

逆に本格的にHaskell(含む他の関数型言語)に触れたい、商用投入したい/してるプロダクトに触れる必要がある、というのでしたらその言語に特化した他の本を購入されたほうがいいかと思います。