2

我正在尝试使用 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函数无法编译,因为我需要tellStructmonad 上使用,而不是Collision. 有可能吗?

4

1 回答 1

3

实际上,具有多个相似的层是一种情况,这种mtl方法意味着lift隐含,正如您提到的那样有麻烦。所以你可以lift明确地使用。

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

因此

foo x = do lift (tell (S False)) ; return x
于 2017-03-03T23:41:20.057 回答