第1回 ふつうのHaskellプログラミング読書会

JavaScriptを勉強している過程で関数型言語に興味をもっているところで、地元横浜でHaskellの勉強が開催されると言うことで参加しました。予備知識無しで、「ふつうのHaskellプログラミング ふつうのプログラマのための関数型言語入門」を読んで行くといった内容の勉強会です。

読書会は初参加だったのでどんなことをするのかと不安だったのですが、まとまったページを一人の方が音読して、疑問になった事があったらその都度皆で議論していくというスタイルでした。これは、初学者としてはとてもありがたいスタイルだと思います。参加者の方々の中には、昔Haskellやってたけど、今はやってないから勘を取り戻すために参加したという方もいるので、ありがたい解説付きでHaskell入門ができます。
第1回では、第1,2章を読みました。

1.Haskellプログラミングを始めよう

前提として、「ふつうのHaskellプログラミング ふつうのプログラマのための関数型言語入門」は、関数型言語未経験でJava、Cの様なプログラミングの経験者を対象としています。ので、Javaと比較しながらHaskellの解説が進んでいきます。

1章のポイント

関数は、引数と返り値の対応関係をコードにしたもので、必ず値を返す(値を返さない、void型の関数は無い)。

Haskellの長所

  • 柔軟なプログラミング
  • コンパイル時の型チェックが強力
  • 可読性の高いコード
  • 遅延評価

Haskellに限らず、関数プログラミングは関数自体を値として活用できるので、「高階関数」の様な、関数を引数、返り値として扱う様な柔軟なコードを書けます。JavaScriptも関数はオブジェクトと同様に扱えるので、同じことができますね。

Haskellでは再代入が無い!Haskellでは、一旦初期化した変数には再び代入をすることができません。これによって、グローバル変数の恐怖から開放されます。変数のスコープが小さくなり、かつ値が変わらないということが保証されます。

遅延評価については、本文事態も若干後に続く章での説明があるせいか濁し気味だったので軽くふれてます。Haskellでは、まず関数を評価しておいて、必要になったら引数だけを評価するといったことが行われます。逆にJavaでは、引数を評価した後に関数を評価します。以下のコードであれば、(1 + 2)が評価され"3"になってからprintlnメソッドが評価されます。

system.out.println(1 + 2);

Haskellの落とし穴としては、大雑把に言えば「難しそう」というイメージがあるということに集約されるっぽいです。小難しい用語や、数学的なサンプルコードは置いといて実践しながらHaskellの特徴を学んでいこうよ。というのが本書の趣旨の様でした。

本書では、Hasekllの処理系としてGHCが採用されています。最新は、バージョン6.12.1としてリリースされていますが、標準ライブラリが結構省かれているので基本的には6.10系が基本とのことです。公式では、Haskell Platformを利用することが推奨されています。

GHCをインストールすれば、コンパイラのGHC、インタプリタのghci、コンパイル無しでHaskellプログラムを実行できるrunghcが使えるようになります。

2.Haskellの基礎

要点としては、インデントがブロックを表現する(=レイアウト)、リストの概念を通して、簡易版Linuxコマンドを実装します。組込の関数を使うので2、3行のコードでcat、tail、headの様なコマンドを実装出来ます。

一見して分かりにくかったのは、「引数に関数を適用する(apply)」や、「変数を値に束縛する(bind)」といった言い方でしょうか。

-- 引数"Hello, Wolrd!"にputStrLn関数を適用する
putStrLn "Hello, World!"

-- 変数を値に束縛する
cs <- getContents

「関数に引数を渡して呼び出す」、ではなくて「引数に関数を適用する」です。変数の初期化は、変数と値を結びつける行為なので「変数を値に束縛する」(変数が束縛される)ということになります。

Haskellでの変数の命名規則は、「n(整数)、ns(整数のリスト)、c(文字)、cs(文字列)」の様な短い変数名を付けることが慣習の様です。

次回からは、予習しつつJavaScriptと比較しながら読書会に参加した方が良いかも。