Writer Monad 嵌套两次
Writer Monad Nested Twice
我正在尝试使用 Monad Transformers 嵌套 writer 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
因此
foo x = do lift (tell (S False)) ; return x
我正在尝试使用 Monad Transformers 嵌套 writer 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
因此
foo x = do lift (tell (S False)) ; return x