Haskell 编写器Monad嵌套了两次

Haskell 编写器Monad嵌套了两次,haskell,monads,monad-transformers,writer-monad,Haskell,Monads,Monad Transformers,Writer Monad,我正在尝试使用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 Mon

我正在尝试使用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
函数没有编译,因为我需要在
Struct
monad上使用
tell
,而不是
Collision
。有可能吗?

有多个类似的层实际上是一种情况,
mtl
方法,它旨在使
lift
隐式化,正如您所提到的那样存在问题。因此,您可以显式地使用
lift

lift :: Writer Struct Bool -> WriterT Collision (Writer Struct) Bool
因此


谢谢请允许我再问一个问题。如何定义函数展开所有这些,类似于
runWriter
。签名:
runW::CSInt->(Int,Bool,Bool)
您可以使用
runWriter
/
runWriterT
,或者只需在
CSInt
上进行模式匹配(请参阅
writer
的定义)。
foo x = do lift (tell (S False)) ; return x