我試圖將Data.Binary.Put monad包裝到另一箇中,以便稍後我可以問它「將要寫入多少字節」或「文件中當前位置是什麼」等問題。但即使很瑣碎的包裝如:爲什麼包裝Data.Binary.Put monad會造成內存泄漏?
data Writer1M a = Writer1M { write :: P.PutM a }
or
data Writer2M a = Writer2M { write :: (a, P.Put) }
創建一個巨大的空間泄漏和程序通常崩潰(佔用4GB的RAM後)。以下是我試過到目前爲止:
-- This works well and consumes almost no memory.
type Writer = P.Put
writer :: P.Put -> Writer
writer put = put
writeToFile :: String -> Writer -> IO()
writeToFile path writer = BL.writeFile path (P.runPut writer)
-- This one will cause memory leak.
data Writer1M a = Writer1M { write :: P.PutM a }
instance Monad Writer1M where
return a = Writer1M $ return a
ma >>= f = Writer1M $ (write ma) >>= \a -> write $ f a
type WriterM = Writer1M
type Writer = WriterM()
writer :: P.Put -> Writer
writer put = Writer1M $ put
writeToFile :: String -> Writer -> IO()
writeToFile path writer = BL.writeFile path (P.runPut $ write writer)
-- This one will crash as well with exactly the
-- same memory foot print as Writer1M
data Writer2M a = Writer2M { write :: (a, P.Put) }
instance Monad Writer2M where
return a = Writer2M $ (a, return())
ma >>= f = Writer2M $ (b, p >> p')
where (a,p) = write ma
(b,p') = write $ f a
type WriterM = Writer2M
type Writer = WriterM()
writer :: P.Put -> Writer
writer put = Writer2M $ ((), put)
writeToFile :: String -> Writer -> IO()
writeToFile path writer = BL.writeFile path (P.runPut $ snd $ write writer)
我是新來的Haskell,這是沒有SENCE給我,但包裝單子看起來很瑣碎,所以我猜有是我失蹤的事情。
感謝您的期待。
UPDATE: 下面是一個說明該問題的示例代碼:http://hpaste.org/43400/why_wrapping_the_databinaryp
UPDATE2: 還有一個第二部分這個問題here。
你使用什麼編譯器標誌? – 2011-01-28 14:36:27
當你問我用-O2試過(我以前沒有用過),但記憶足跡沒有改變。 – 2011-01-28 14:49:47