したがって、Haskellseq
関数は最初の引数の評価を強制し、2 番目の引数を返します。したがって、これは中置演算子です。式の評価を強制したい場合、直観的にそのような機能は単項演算子になります。だから、代わりに
seq :: a -> b -> b
それはそのようになります
seq :: a -> a
したがって、必要な値が の場合a
、なぜ戻りb
、どのように の戻り値を構築しますかb
。明らかに、私は Haskell を考えていません。:)
したがって、Haskellseq
関数は最初の引数の評価を強制し、2 番目の引数を返します。したがって、これは中置演算子です。式の評価を強制したい場合、直観的にそのような機能は単項演算子になります。だから、代わりに
seq :: a -> b -> b
それはそのようになります
seq :: a -> a
したがって、必要な値が の場合a
、なぜ戻りb
、どのように の戻り値を構築しますかb
。明らかに、私は Haskell を考えていません。:)
考え方としてa `seq` b
は、「評価する」ということではなく、 との間に依存関係をa
作り、評価するときに自分も評価するということです。a
b
b
a
これは、たとえば、これは完全に冗長であることを意味します: を評価するときにa `seq` a
Haskell に評価するように指示しているのです。同じ論理で、引数が 1 つだけでも、単にそれ自体を記述することと何ら変わりはありません。a
a
seq a
a
seq a
どういうわけか評価するだけでa
はうまくいきません。問題は、seq a
それ自体が評価されない可能性がある式であることです。たとえば、ネストされたサンクの奥深くにある可能性があります。そのため、式全体を評価するようになった場合にのみ関連性が高まります。seq a
その時点では、a
とにかくそれ自体を評価していたはずです。
@Rhymoid の厳密な折り畳み ( foldl'
) での使用例は良い例です。acc
私たちの目標は、最終結果を評価するとすぐに中間累積値 ( ) が各ステップで完全に評価されるようにフォールドを作成することです。これはseq
、累積値と再帰呼び出しの間にa を追加することによって行われます。
foldl' f z (x:xs) =
let z' = f z x in z' `seq` foldl' f z' xs
これを、フォールド内のseq
各アプリケーション間の長いチェーンとして視覚化し、それらすべてを最終結果に接続することができます。f
このようにして、最終的な式 (つまり、リストを合計して得られる数値) を評価すると、中間値 (つまり、リストをたどったときの部分合計) が厳密に評価されます。