IO モナドは難しい

ふつける p.108 に遅延評価の説明として

myIf :: Bool -> a -> a -> a
myIf True  t e = t
myIf False t e = e

このように、if を関数で書いてみました。次のプログラムを使って動作を試しましょう。

main = do myIf (True) (putStrLn "then") (putStrLn "else")

このプログラムが「then」だけを表示すればアクション「putStrLn "else"」は評価されていないことがわかります。

とあるが、「putStrLn "else"」を評価した時に出力がされるわけではないので、「評価されていないことがわか」るわけではないと思う。逆に言うと、「putStrLn "else"」 も評価されているのに「then」だけを表示しているかもしれない、ということだ。
実際、

data Nanika a = Nanika !a

main = let nanika = Nanika (putStrLn "foo") in
       case nanika of
         Nanika _ -> putStrLn "bar"

の「putStrLn "foo"」は評価される(例えば 1 `div` 0 などに置き換えてみるとわかる)が、「foo」が出力されるわけではない。IO モナドは難しいなあ。OCaml みたいな正格で非純粋な言語に慣れているとうっかり罠に嵌まるかもしれない。