seq関数
seq :: a -> b -> b
ただし、a→bの順序で評価されるとは限らない
the expression seq a b does not guarantee that a will be evaluated before b ref これを「a→bの順で評価される」と書いてる解説ブログを何件か見かけたmrsekut.icon
弱頭部正規形でないものを弱頭部正規形に変換する例
code:ghci(hs)
ghci> let x = 1 + 2 :: Int -- 1+2はまだ評価されていない
ghci> :sprint x
x = _ -- まだthunkのままであることを確認
ghci> seq x () -- 弱頭部正規形に簡約
()
ghci> :sprint x
x = 3 -- 簡約されている
code: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
code:ghci(hs)
-- ヘイヘイHaskell p.13
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
ghci> sum xs
65
ghci> :sprint xs
既に弱頭部正規形になっているものに適用しても何も変わらない例
code:ghci(hs)
ghci> let x = Just (1+2) :: Maybe Int -- 既に弱頭部正規形
ghci> :sprint x
x = Just _
ghci> seq x ()
()
ghci> :sprint x
x = Just _ -- seqの実行前後で変わらない
code:ghci(hs)
ghci> seq (\x -> undefined) () -- 既に弱頭部正規形なので、errorにならない
code:ghci(hs)
ghci> seq error () -- 既に弱頭部正規形なので、errorにならない
参考