Haskellに2つの異なるライタータイプのモナドがあるのはなぜですか?私にとって直感的には、「strict writer monad」を読むことは、<>
が厳密であることを意味するため、ログにサンクが蓄積することはありません。ただし、ソースコードを見ると、そうではないことがわかります。
-- Lazy Writer
instance (Monoid w, Monad m) => Monad (WriterT w m) where
-- ...
m >>= k = WriterT $ do
~(a, w) <- runWriterT m
~(b, w') <- runWriterT (k a)
return (b, w <> w')
厳密なバージョンでは、パターンは反駁できません。つまり、パターン~
が欠落しています。したがって、上記で発生するのは、m
評価k a
されず、サンクとして保存されることです。厳密なバージョンでは、タプルパターンと一致するかどうかを確認するために評価され、結果がに送られ<>
ます。どちらの場合も、>>=
何かが実際に結果の値を要求するまで、は評価されません。だから私が理解しているのは、レイジーバージョンとストリクトバージョンの両方が同じことをするということです。ただし、レイジーはサンクを>>=
生成しrunWriterT
、ストリクトはサンクを生成し<>
ます。
これは私に2つの質問を残します:
- 上記は正しいですか、それともここでの評価を誤解していますか?
<>
独自のラッパーとインスタンスを作成せずにstrictを達成できますか?