我正在尝试使用Monad变形金刚两次嵌套编写器monad。这是一幅草图:
import Control.Monad.Identity
import Control.Monad.Writer
data Struct = S Bool
instance Monoid Struct where
mempty = S True
mappend (S a) (S b) = S (a && b)
data Collision = C Bool
instance Monoid Collision where
mempty = C False
mappend (C a) (C b) = C (a || b)
type CSInt = WriterT Collision (WriterT Struct Identity) Int
foo :: Int -> CSInt
foo x = do (tell (S False)) ; return x
foo
函数无法编译,因为我需要在tell
monad上使用Struct
,而不是Collision
。它有可能吗?
答案 0 :(得分:3)
有多个相似的图层实际上就是一种情况,mtl
方法是隐含的lift
方法,如你所提到的那样有问题。因此,您可以明确使用lift
。
lift :: Writer Struct Bool -> WriterT Collision (Writer Struct) Bool
因此
foo x = do lift (tell (S False)) ; return x