を使用しdeepSeq
ます。と同じように使用されseq
ます。次のように組み込みます。
myForkedProcess :: IORef [[Color]] -> IO ()
myForkedProcess ref = do let colors = takesAgesToRun
deepSeq colors $ writeIORef ref colors
これにより、「writeIORef」呼び出しの前に「色」が完全に評価されます。
これを機能させるには、のNFData
インスタンスが必要ですColor
。正確にこれを書く方法は色の定義に依存しますが、ここに2つの例があります:
-- just for reference
data Color = Color Double Double Double
instance NFData Color where
rnf (Color r g b) = r `seq` g `seq` b `seq` ()
-- closer to the likely actual implementation for Color
data Color2 = Color2 !Double !Double !Double
instance NFData Color2 where
-- the default implementation is fine
たとえば、Color
Colorがである場合は常に、色のすべてのコンポーネントが完全に評価されていることを確認する必要があります[1]。それがseq
sが行うことです。各コンポーネントがであることがわかっているため、ここseq
の代わりに使用できます。したがって、seqによって完全に評価されます。コンポーネントがより複雑なデータ型である場合は、NFDataインスタンスを作成するときに使用する必要があります。deepSeq
Double
deepSeq
それColor2
は少し簡単です。強打パターンのため、コンポーネントはいつで完全に評価されるかがわかりColor2
ます。Color2
これは、バングパターンのために完全に評価される弱い頭の通常の形式に評価されるデフォルトの実装を使用できることを意味します。
rnf
Control.Parallel.Strategiesと組み合わせて使用すると主に役立ちます。これが現在の定義ですdeepSeq
deepseq :: NFData a => a -> b -> b
deepseq a b = rnf a `seq` b
deepseqが行うのはrnf
、その出力()が評価されることを呼び出して保証することだけです。これは実際にrnf
直接使用する唯一の方法です。
[1] Haskellは、パターンマッチングと。の2つの一般的な評価方法しか提供していませんseq
。他のすべては、これらの一方または両方に基づいて構築されています。NFData Colorインスタンスの場合、Color
最初にコンストラクターとのパターンマッチングによってWHNFに評価されColor
、次にコンポーネントがseqによって評価されます。
もちろん、ものを評価するための3番目の高度に専門化された方法もあります。つまり、 main :: IO ()
を評価するために関数が実行され()
ます。