簡體   English   中英

我如何才能懶惰地流進折疊架?

[英]How do I get lazy streaming into the foldl'?

一個人如何制作自己的流代碼? 我當時隨機生成了約10億對戰斗甲板,但我希望它們能被懶散地流進折疊架,但空間泄漏了! 這是代碼的相關部分:

main = do
    games <- replicateM 1000000000 $ deal <$> sDeck --Would be a trillion, but Int only goes so high
    let res = experiment Ace games --experiment is a foldl'
    print res --res is tiny

當我用-O2運行它時,它首先開始凍結我的計算機,然后該程序消失,並且計算機恢復了運行(然后Google Chrome瀏覽器有了它要消耗我所有資源的資源,要罵我。)

注意:我嘗試了unsafeInterleaveIO,但沒有成功。

完整代碼位於: http : //lpaste.net/109977

replicateM不執行延遲流傳輸。 如果您需要流式處理單聲道操作的結果,則應使用conduitpipes類的庫。

您的示例代碼可以編寫為支持類似這樣的管道流:

import Data.Conduit
import qualified Data.Conduit.Combinators as C

main = do
    let games = C.replicateM 1000000 $ deal <$> sDeck
    res <- games $$ C.foldl step Ace
    -- where step is the function you want to fold with
    print res

Data.Conduit.Combinators模塊來自conduit-combinators軟件包。

作為一個快速和骯臟的解決方案,你可以實現一個流版本replicateM使用懶IO。

import System.IO.Unsafe

lazyReplicateIO :: Integer -> IO a -> IO [a] --Using Integer so I can make a trillion copies
lazyReplicateIO 0 _   = return []
lazyReplicateIO n act = do
    a <- act
    rest <- unsafeInterleaveIO $ lazyReplicateIO (n-1) act
    return $ a : rest

但我建議使用適當的流媒體庫。

等效pipes解決方案是:

import Pipes
import qualified Pipes.Prelude as Pipes

-- Assuming the following types
action :: IO A
acc    :: S
step   :: S -> A -> S
done   :: S -> B

main = do
    b <- Pipes.fold step acc done (Pipes.replicateM 1000000 action)
    print (b :: B)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM