4

'dである長期実行プロセスがありforkIO、ピクセルカラー値を生成します。

takesAgesToRun :: [[Color]]

myForkedProcess :: IORef [[Color]] -> IO ()
myForkedProcess ref = do let colors = takesAgesToRun
                         writeIORef ref colors

(ここで、Color3つの値を保持しDoubleます)。

予想どおり、の「反対側」で読み取った場合、IORef保存された値は単なるサンクであるため、メインプロセスをブロックします。

通常の形式で値を完全に評価する必要があることはわかってい[[Color]]ますが、それを実現するには2つの方法があるようです。さらに、どちらをコードに組み込むかがわかりません。

どうすればいいですか?rnf、、deepSeqまたはその他のスレッド戦略を使用しますか?これらの1つが優先され、他は非推奨になりますか?そして、それは私のコードにどのように適合しますか?

(PSは、画像を色のリストのリストとして保存するのはばかげているという事実を無視してください。これは、コードの単純化されたバージョンにすぎません)。

4

1 に答える 1

5

を使用し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

たとえば、ColorColorがである場合は常に、色のすべてのコンポーネントが完全に評価されていることを確認する必要があります[1]。それがseqsが行うことです。各コンポーネントがであることがわかっているため、ここseqの代わりに使用できます。したがって、seqによって完全に評価されます。コンポーネントがより複雑なデータ型である場合は、NFDataインスタンスを作成するときに使用する必要があります。deepSeqDoubledeepSeq

それColor2は少し簡単です。強打パターンのため、コンポーネントはいつで完全に評価されるかがわかりColor2ます。Color2これは、バングパターンのために完全に評価される弱い頭の通常の形式に評価されるデフォルトの実装を使用できることを意味します。

rnfControl.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 ()を評価するために関数が実行され()ます。

于 2011-07-12T11:46:02.200 に答える