syd_sydの日記

2006-06-13

[][] evaluate と return : 項の強制評価

Control.Exception.evaluate

evaluate :: a -> IO a

returnと似て非なるもの。渡された項を評価する。これが効いてくるのは、「無限に続く(止まらない) 計算」や「エラーを投げる計算」を食わせた時。

例:

do
  return $ 1 `div` 0 -- 0除算
  putStrLn "I'm still alive!"

I'm still alive!

となるのに対し*1

do
  Control.Exception.evaluate $ 1 `div` 0 -- 0除算
  putStrLn "I'm still alive!"

は 1/0が評価されて、

*** Exception: divide by zero

となる。

必ず評価する、という点ではseq と似てるけど、seq は第一引数を捨てるし、 evaluate は IOモナドを返す点で違う(本文参照)。 次のthrowとthrowIOの違いに似てる?

*1:return (1`div`0) >>= \_-> putStrLn "..." となり、遅延評価により除算されない。これに対し return (1`div`0) >>= \x-> putStrLn $ show x とやればputStrLnに必要なため1/0が評価され例外がraiseされる。