golden-luckyの日記

ツイッターより長くなるやつ

Haskell 解説本 小史

日本語圏におけるHaskellの解説本には、これまで4回の波がありました。 それを思い出しながら、最後に『プログラミングHaskell 第2版』の紹介をします。

f:id:golden-lucky:20190802181136p:plain

第1波

Haskell解説本の1つめの波は、2006年、『入門Haskell』と『ふつうのHaskell』が出版された頃にありました。 このうち、『入門Haskell』は(おそらく)日本初のHaskell本です。

『入門Haskell』(2006年) 『ふつうのHaskell』(2006年)

『ふつうのHaskell』は、書名だけを見ると「特殊な言語」であるHaskellを「ふつう」に説明している本であるように思えるのですが、実はそうでもなくて、淡々と部品の説明をしていく感じの内容です。 そのぶん例題はあまりなくて、最後にWikiエンジンをがっと作ってみるという構成でした(当時はWikiエンジンを作るのが流行っていたのです)。

一方、『入門Haskell』のほうは、冒頭でまず wc コマンドを実装してHaskellプログラミングの全体像をみせたり、最後にはちょっとしたゲームを開発したり、わりと教育的な内容の本でした。 Haskellを多少は使えるようになった今になって考えると、こういう構成で説明できること自体が、とってもHaskellらしさを伝えている本だったなと思います。ぼくはこの本でHaskellに最初にふれました。

第2波

2つめの波は、2009年ごろ、『Real World Haskell』と『プログラミングHaskell』が出版されたタイミングでしょう。

『Real World Haskell』(2009年) 『プログラミングHaskell』(2009年)

『Real World Haskell』は、「実戦」というキャッチコピーが示すように、仕事や実務でHaskellを使うための情報が詰め込まれた本です。 画像解析をしたり、FFI経由で正規表現のCライブラリを使ったり(当時のHaskellには十分な正規表現のサポートがなかった)、ParsecでCSVのパーザを作ったり、ネットワークプログラミングをしたり、分散並行プログラミングをしたりします。 全部は読んでなかったんですが、いま目次を見たところ、STMの話とかもすでに載ってたらしいので、あらためて読み返してみたくなりました。

一方の『プログラミングHaskell』は、『Real World Haskell』の対局にあるような本で、Haskellを通して「プログラミングそのもの」が学べます。 「プログラミングそのもの」ってなんだよって話ですが、この本で学ぶのは、いわゆる関数プログラミングというやつです。 「(変数への代入ではなく)関数の組み合わせで高度なプログラムの全体を構築していく方法をHaskellというプログラミング言語で解説していく」ことが、『プログラミングHaskell』という本の主眼でした。

この『プログラミングHaskell』の改訂が出たというのが、この記事で唯一記憶して頂きたい話です。

第3波

3つめの波は、『すごいHaskellたのしく学ぼう』と『関数プログラミング入門 Haskellで学ぶ原理と技法』が出版された2012年です。

『すごいHaskellたのしく学ぼう』(2012年) 『関数プログラミング入門 Haskellで学ぶ原理と技法』(2012年)

『すごいHaskellたのしく学ぼう』は、おそらくこの記事を読んでいる人全員が少なくとも書名だけは知っている本だと思います。 へたうまなイラストに目がいきがちですが、「Haskellの解説手法」という観点でもひとつの金字塔を打ち立てた本で、その意味でも「すごい」本でした。

具体的には、関手(ファンクター)→アプリカティブ→モナドという解説の流れは、この本が作り出しました。 この説明の流れは、「同じパターンで定義できる関数」をHaskellでどのようにまとめるかについて、『Real World Haskell』のころには知られていなかった知見を反映したものです。

これ以降に出版された解説書では、この流れを意識するか踏襲するかして、モナドが解説されていると思います。 それ以前はどうだったかというと、アプリカティブを経由せずにモナドへと一気に直登するハードモードが一般的でした。 実際、同じ年に翻訳は出たものの原書が出版されたのは1998年である『関数プログラミング入門 Haskellで学ぶ原理と技法』は、このハードモードです。 そのころにはまだアプリカティブが発見されてなかった(よく知られてなかった?)からしかたありません。

では『関数プログラミング入門 Haskellで学ぶ原理と技法』には今では価値がないのかというと、そんなことはなくて、等式変形によって関数を作り出す「運算」の方法を学べます。 この運算、より応用的なHaskell本である『関数プログラミングの楽しみ』や『関数プログラミング 珠玉のアルゴリズムデザイン』では大活躍します。 ただ、次に紹介する第4波において本書の改訂版の翻訳にあたる『Haskellによる関数プログラミングの思考法』が出ているので、いまならそちらを読むほうが楽かもしれません。

第4波

第4の波は、2017年前後のバラエティー豊かなHaskell解説書の登場です。 あまりにバラエティーが豊かなうえに、時期的にも隔たりがあるので、全部ひっくるめるのはちょっと乱暴という自認はあるんですが、とりあえず並べます。

『関数プログラミング実践入門 増補版』(2016年、最初の版は2014年) 『Haskell 教養としての関数型プログラミング』(2017年) 『Haskell入門 関数型プログラミング言語の基礎と実践』(2017年) 『Haskellによる関数プログラミングの思考法』(2017年)

関数プログラミング実践入門』は、実際にはHaskellに限定した本ではありません。 ただ、他の言語におけるモナドの話とかも入ってるのでむしろお得だし、Haskellの実務的な側面に対する解説に価値がありました。 個人的には、GHCを使って開発するときに知りたかったことが書いてあって、とてもうれしい本でした。

追記:2014年に最初の版が出ている『関数プログラミング実践入門』がこの第4波に含まれているのは、ぼくが最初の版を2016年だと勘違いしていたからです。当然、記事も間違っていたのですが、同書の著者である大川さんの指摘で上記の表も修正してあります。

Haskellによる関数プログラミングの思考法』は、Haskellそのものですが、実務的なプログラミングではなく、運算の技法を通して関数プログラミングの何たるかを説明する本です。

Haskell 教養としての関数型プログラミング』と『Haskell入門 関数型プログラミング言語の基礎と実践』については、 ちゃんと読んでいないので内容については何も言えないのですが、 目次を見る限り関手→アプリカティブ→モナドにそってHaskellをひととおり理解できることが目指されているのだろうと感じています。 特に『Haskell入門』のほうは、実務でよく見かける例題が豊富にあるようで、今では古くなってしまった『Real World Haskell』の位置を埋めてくれる本のように思います。

『プログラミングHaskell』が改訂されます

ここからは宣伝です。 第2波で紹介した『プログラミングHaskell』は、原書は2016年に改訂されていたのですが、これがついに翻訳されて発売が開始されました!

www.lambdanote.com

上記では、旧版である『プログラミングHaskell』について、こんなふうに要約してました。

「(変数への代入ではなく)関数の組み合わせで高度なプログラムの全体を構築していく方法をHaskellというプログラミング言語で解説していく」ことが、『プログラミングHaskell』という本の主眼でした。

第2版でも、この主眼はまったく変化していません。 (関数)プログラミングそのものを学ぶための教材としてのHaskellの解説書というコンセプトはそのままに、 Haskellのコードの見た目が数式による表現から等幅フォントによる表現に変わったり、 解説に使われているHaskellの実装がHugsといういまでは滅多に見かけない処理系からGHCになったりしています。 もっとも、処理系に依存した話はもともとあまりないし、これらはあくまでも表面的な変化だといえます。

では、第2版は旧版から表面的な改修を施したものにすぎないのでしょうか?

もちろんそんなことはありません。 第2版で個人的にもっとも進化したなと感じてるのは、型クラスに基づいて諸概念が整理された結果、 「型を使ってプログラミングするとはどういうことか」をより実感できるようになった点だと思っています。

第2版ではプログラミングにおける型の理解が深まると思う

個人的に、Haskellの型って、大きく分けて以下の2種類の用途で使ってるような気がするんですよね (ぼくがHaskellで何かを書いてるときにこう考えてる、という話なので、ピントがずれてる可能性はあります)。

  • データとしての型
  • 定義が同じような形をしている関数を、同じ仲間だと思って扱うための道具としての型(型クラス)

前者は、いわゆる代数的データ型として、Haskellらしいプログラミングのスタイルの根っこにあるやつです。 解きたい問題を「型」でとらえて、その型の上でパターンマッチとかしまくって処理を宣言的に書いていくというのが、ぼくのなかではHaskellらしいプログラミングです。 型のこういう側面については、もちろん初版でも強調されて説明されてたんですが、この第2版では前半を上回る物量でそれを体感できます。 ここで物量と言っているのは、単なるページ数の増加ではなく、例題の増強です。 にもかかわらず、説明のスタイルも、この間の他書における解説の進化に影響されてか、全体にかなりすっきりとした姿になっています。

後者における型については、旧版ではまったくと言っていいほど説明には出てきてませんでした。 実際のところ、Haskellで書き捨てのプログラムを書いているようなときは、あまりこういう観点で型を使う機会はない気がします。 定義の形が同じものを同じように扱うというとLispのマクロが思い浮かびますが、 Lispのマクロも、最初から「よしマクロだ」と意気込んで導入することは少なくて、 なんか関数をいくつか書いてみたら同じような形が現れるのでマクロにできるな、みたいな感じで導入することが多いと思うんですよね。 もちろん、イディオム的に最初からマクロが使えそうだと判明しているケースはあるし、人によってはマクロでプログラムを考えられるのかもしれないので、あくまでも個人の経験に基づく感想です。

で、話を戻すと、Haskellではそういう「なんか同じようなパターンだからまとめたい」も型ベースで扱います(Lispのマクロと背景でなにか繋がってたりするんですかね?)。 とはいえ、すでに触れたように、ぼくみたいなゆるふわなHaskellユーザーが自分でそういうパターンの抽象化を考える必要に迫られる機会はあまりありません。 なにせ型ベースなので、Lispのマクロより数学的な制約があって、そのためモナド則みたいなのを考えないといけないし。

でも、いまのHaskellって、アプリカティブとかFoldableとかTraversableみたいな、型ベースで抽象化済みの仕掛けが標準で入ってるんです。 なので、わりと単純なプログラムでも、ほかの人がそういうやり方で抽象化してくれた土台に乗っかって自分のプログラムを書くことになります。 だから、少なくとも抽象化のノリを理解できていないと、Hoogleで関数を検索するのも難しくなってしまった。

そんなわけで、この第2版でも、モナドの説明がアプリカティブ経由になったり、Foldable/Traversableを説明に取り込んだり、そういうのをしっかりとやっています。 説明を表面的に増やしただけでないので、結果として型の後者の側面にも光が当たることになり、型についての理解が旧版よりも深まってしまう、そんな一冊になってるような気がしています。

ここで買えます

プログラミングHaskell 第2版(紙書籍+電子書籍)www.lambdanote.com

以下はラムダノートのお知らせページからの引用。

「紙書籍+電子書籍」版のお求めでも、「電子書籍のみ」版のお求めでも、いますぐPDFのダウンロードが可能です。紙書籍については、8月22日(日)以降の発送開始を予定しています。書店(オンライン書店を含む)での紙書籍の発売も8月22日以降を予定しております。

なお、直販サイトでのお求めにあたってユーザ登録などは不要です(ただ、ユーザ登録をしていただくと、購入済み電子書籍の再ダウンロードが簡単にできたり、ときどき思いがけない特典があったりします)。