[英]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
不執行延遲流傳輸。 如果您需要流式處理單聲道操作的結果,則應使用conduit
或pipes
類的庫。
您的示例代碼可以編寫為支持類似這樣的管道流:
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.