作家Monad嵌套两次

时间:2017-03-03 23:29:32

标签: 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 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。它有可能吗?

1 个答案:

答案 0 :(得分:3)

有多个相似的图层实际上就是一种情况,mtl方法是隐含的lift方法,如你所提到的那样有问题。因此,您可以明确使用lift

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

因此

foo x = do lift (tell (S False)) ; return x