「ふつうの Haskell プログラミング」がいけてない

「ふつうの Haskell プログラミング」という本があるのだが、その本にある「標準入出力から読み込んだ文字列のバイト数を返すコマンド countbyte を作れ」という練習問題がいけてない。

普通に考えれば

main = do cs <- getContents
          print $ length cs

で問題なさそうなものである。これでコンパイルして

countbyte < hoge.txt

とかやるとちゃんと動くらしいのだが、単に

countbyte

とだけ打ち込んで、適当に文字列を入力して Enter を押してもうんともすんとも言わない*1。何故か。

答は「遅延評価」である。Haskell は遅延評価が基本である。length 関数はリストを最後まで読み込まないと評価されないのでこのような現象が起きてしまう。同章のサンプルである cat コマンド

main = do cs <- getContents
          putStr cs

に関してはそのようなことがないので意図したとおりに動くのだが、countbyte に関してはそうはならない。

そして何よりいけてないのが、実際に問題の解答を見ると、最初に紹介したコードがまんま書いてあるのだ。解答が意図通りに動かないってどういう料簡じゃ ! (ぷんすか)

*1:Enter を押した後に Ctrl + Z を押して Enter を押すと結果を出力して一応止まるが、1 回目の Enter もバイト数に含まれるため意図した結果とは言い難い。