在mtl库中,我看到了以下定义MonadWriter:
class (Monoid w, Monad m) => MonadWriter w m | m -> w where
#if __GLASGOW_HASKELL__ >= 707
{-# MINIMAL (writer | tell), listen, pass #-}
#endif
-- | @'writer' (a,w)@ embeds a simple writer action.
writer :: (a,w) -> m a
writer ~(a, w) = do
tell w
return a
-- | @'tell' w@ is an action that produces the output @w@.
tell :: w -> m ()
tell w = writer ((),w)
Run Code Online (Sandbox Code Playgroud)
所以writer并tell递归地互相调用.但我无法理解它是如何工作的.有停止条件吗?这是否因为Haskell的懒惰而起作用?任何人都能发光吗?
Ale*_*ing 11
注意MINIMAL注释:
{-# MINIMAL (writer | tell), listen, pass #-}
Run Code Online (Sandbox Code Playgroud)
这告诉GHC需要实现哪些类方法来创建一个完整的实例.通常,这组方法是由编译器推断的 - 它只是没有默认实现的方法集 - 但在某些情况下,显式指定它是有用的.这就是这种情况.
该MINIMAL用于注释MonadWriter说,listen与pass必须始终实现,这是有道理的,因为这些方法没有任何的默认实现.它接着说更有趣的东西:要么writer 还是 tell必须执行,但不一定都.
这样就可以了,因为如果实例提供了一个实现writer,那么默认实现tell将用于根据提供的writer实现来实现它.同样,如果实例提供tell但不是,则反转将为真writer.该MINIMAL注释从供给的实现保护的情况下没有,所以没有完整的情况下都不能有同时使用的默认实现一次.