パターンマッチ

expandのバージョン2を作成。プログラムはこんなのですが説明なしでは意味不明。

tabStop = 8

main = do cs <- getContents
          putStr $ expand cs

expand :: String -> String
expand cs = concatMap expandTab cs

expandTab :: Char -> String
expandTab '\t' = replicate tabStop ' '
expandTab c    = [c]

expandTabの定義が二つあって、一つ目は引数の部分が'\t'になっています。これがパターンマッチで、引数が'\t'の場合にこちらが呼ばれるそうです。引数が変数名になっている場合は任意の値のときに呼ばれるそうです。マッチの評価は上から順番。

これって条件式を書けるのであれば、すごくすっきり書けますね。こんな感じで。

foo n < 0 = ...
foo 0     = ...
foo n > 0 = ...

新しい関数はcancatMapとreplicate。cancatMapはcancatとmapを合わせたもの。replicateはPerlのx演算子のようなもの。

一行目の tabStop = 8 は変数tabStopに8を代入と言いたくなりますが、代入ではなく束縛です。