seq関数
seq :: a -> b -> b
a
と
b
を
弱頭部正規形まで評価してから、
b
をそのまま返す
ただし、 a
→ b
の順序で評価されるとは限らない
>the expression seq a b does not guarantee that a will be evaluated before b ref
これを「
a
→
b
の順で評価される」と書いてる解説ブログを何件か見かけた

弱頭部正規形でないものを弱頭部正規形に変換する例
ghci(hs)ghci> let x = 1 + 2 :: Int -- 1+2はまだ評価されていない
ghci> :sprint x
x = _ -- まだthunkのままであることを確認
ghci> seq x () -- 弱頭部正規形に簡約
()
ghci> :sprint x
x = 3 -- 簡約されている
ghci(hs)-- ヘイヘイHaskell p.12
ghci> let x = 1 + 1 :: Int
ghci> let z = id (x,x+1)
ghci> :sprint z
z = _
ghci> seq z () -- 弱頭部正規形に簡約
()
ghci> :sprint z
z = (_,_) -- 中身はthunk
ghci> seq x () -- xを弱頭部正規形に簡約
()
ghci> :sprint z
z = (2,_) -- x+1の方はthunk
ghci(hs)-- ヘイヘイHaskell p.13
ghci> let xs = map (+1) [1..10] :: [Int]
ghci> :sprint xs
xs = _
ghci> seq xs () -- 弱頭部正規形に簡約。(:)がコンストラクタ
()
ghci> :sprint xs
xs = _ : _ -- mapの定義内の f x : map f xs がthunkになっている
ghci> length xs
10
ghci> :sprint xs
xs = [_,_,_,_,_,_,_,_,_,_] -- lengthの定義に因る。(f x)はthunkのまま
ghci> sum xs
65
ghci> :sprint xs
xs = [2,3,4,5,6,7,8,9,10,11]
既に弱頭部正規形になっているものに適用しても何も変わらない例
ghci(hs)ghci> let x = Just (1+2) :: Maybe Int -- 既に弱頭部正規形
ghci> :sprint x
x = Just _
ghci> seq x ()
()
ghci> :sprint x
x = Just _ -- seqの実行前後で変わらない
ghci(hs)ghci> seq (\x -> undefined) () -- 既に弱頭部正規形なので、errorにならない
ghci(hs)ghci> seq error () -- 既に弱頭部正規形なので、errorにならない
参考