为什么 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 产生runWriterT
thunk,strict 产生<>
thunk。
这给我留下了两个问题:
- 以上是对的,还是我误解了这里的评价?
- 我可以
<>
在不编写自己的包装器和实例的情况下完成严格吗?