为什么 Haskell 中有两种不同的 Writer 类型的 monad?对我来说,直觉上,阅读“严格的作家单子”意味着<>严格,所以日志中没有 thunk 积累。但是,查看源代码,事实证明并非如此:
-- 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没有被评估,而是存储为 thunk。在严格的版本中,它们被评估以检查它们是否匹配元组模式,结果被馈送到<>. 在这两种情况下,>>=直到某些东西实际需要结果值时才会评估。所以我理解它的方式是惰性和严格版本都做同样的事情,除了它们在定义内的不同位置有 thunk >>=:lazy 产生runWriterTthunk,strict 产生<>thunk。
这给我留下了两个问题:
- 以上是对的,还是我误解了这里的评价?
- 我可以
<>在不编写自己的包装器和实例的情况下完成严格吗?