我正在尝试将 Data.Binary.PutM monad 修改为 monad 转换器。所以我从改变它的定义开始
newtype PutM a = Put { unPut :: PairS a }
到
newtype PutM a = Put { unPut :: Identity (PairS a) }
然后当然我改变了return和>>=函数的实现:
从:
return a = Put $ PairS a mempty
{-# INLINE return #-}
m >>= k = Put $
let PairS a w = unPut m
PairS b w1 = unPut (k a)
in PairS b (w `mappend` w1)
{-# INLINE (>>=) #-}
m >> k = Put $
let PairS _ w = unPut m
PairS b w1 = unPut k
in PairS b (w `mappend` w1)
{-# INLINE (>>) #-}
到:
return a = Put $! return $! PairS a mempty
{-# INLINE return #-}
m >>= k = Put $!
do PairS a w <- unPut m
PairS b w1 <- unPut (k a)
return $! PairS b $! (w `mappend` w1)
{-# INLINE (>>=) #-}
m >> k = Put $!
do PairS _ w <- unPut m
PairS b w1 <- unPut k
return $! PairS b $! (w `mappend` w1)
{-# INLINE (>>) #-}
好像 PutM monad 只是一个 Writer monad。不幸的是,这(再次)造成了空间泄漏。我很清楚(或者是吗?)ghc 正在推迟某个地方的评估,但我试图按照一些教程的建议$!
而不是$
任何地方放置,但这并没有帮助。另外,如果内存分析器向我显示的内容是这样的,我不确定它有什么帮助:
.
为了完整起见,这是我在使用原始 Data.Binary.Put monad 时得到的内存配置文件:
如果有兴趣,这里是我用来测试它的代码,我用来编译、运行和创建内存配置文件的行是:
ghc -auto-all -fforce-recomp -O2 --make test5.hs && ./test5 +RTS -hT && hp2ps -c test5.hp && okular test5.ps
我希望我的内存泄漏问题不会惹恼任何人。我发现互联网上没有很多关于这个主题的好资源,这让新手一无所知。
感谢您的关注。