Data.Binary.PutM モナドをモナド変換子に変更しようとしています。だから私はそれの定義を変更することから始めました
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 モナドが単なる Writer モナドであるかのように。残念ながら、これは(再び)スペースリークを引き起こしました。ghc がどこかで評価を延期していることは明らかですが、いくつかのチュートリアルで提案されているように、どこにでも配置しようとしまし$!
た$
が、それは役に立ちませんでした。また、次のような場合、メモリ プロファイラーがどのように役立つかわかりません。
.
完全を期すために、これは元の Data.Binary.Put モナドを使用したときに得られるメモリ プロファイルです。
興味がある場合は、テストに使用しているコードと、コンパイル、実行、およびメモリ プロファイルの作成に使用している行を次に示します。
ghc -auto-all -fforce-recomp -O2 --make test5.hs && ./test5 +RTS -hT && hp2ps -c test5.hp && okular test5.ps
メモリ リークに関する私の一連の質問で誰かを悩ませていないことを願っています。インターネット上には、このトピックに関する優れたリソースがあまりないことがわかりました。
ご覧いただきありがとうございます。