Haskellメモ

seq

seq x y は xを評価してからyを評価する。いずれも弱頭部正規形までの評価となる。 中置演算子を用いると x `seq` yと書ける。

seqの定義は以下の通り。

Prelude> :i seq
seq :: a -> b -> b  -- Defined in `GHC.Prim'
infixr 0 `seq`

最も優先度の低い右結合。右結合のため、x `seq` y `seq` z( x `seq` ( y `seq` z ) )となり、評価順序は y -> z -> x となる。 見た目とは評価順序が異なるため注意。

以下のサイトだと、

if'' p x y = p `seq` x `seq` y `seq`  -- p, x, y を評価
             if p then x else y

とあるけど、評価順序は、 y -> if文 -> x -> p という順序となり、y(0除算)が最初に評価されるために例外が発生、ということになる。

正格評価 - ウォークスルー Haskell

しかし実は

x `seq` yはxがyよりも先に評価されることは保証しない。 そういった評価戦略が取りたければpseqを用いれば良い。 seqはパラメータに対して簡約を促すだけであり、評価の順序は保証しない。 そのため、上記については右結合であることは分かるが、それがどういった順序で実行されるかは実装依存(ランタイムの動作次第であり最適化の度合いによって順序が決まる)となる。