【问题标题】:How can I make a Maybe-Transformer MaybeT into an instance of MonadWriter?如何将 Maybe-Transformer MaybeT 变成 MonadWriter 的实例?
【发布时间】:2013-12-15 22:19:23
【问题描述】:

我正在尝试构建一个 MaybeT-Transformer Monad,基于 Real World Haskell 章节 Monad Transformers 中的示例:

data MaybeT m a = MaybeT { runMT :: m (Maybe a) }

instance (Monad m) => Monad (MaybeT m) where
  m >>= f = MaybeT $ do a <- runMT m
                        case a of 
                            Just x -> runMT (f x)
                            Nothing -> return Nothing
  return a = MaybeT $ return (Just a)

instance MonadTrans MaybeT where
  lift m = MaybeT $ do
                     a <- m
                     return (Just a)

这很好用,但现在我想让 MaybeT 成为 MonadWriter 的一个实例:

instance (MonadWriter w m) => MonadWriter w (MaybeT m) where
 tell = lift . tell 
 listen m = MaybeT $ do unwrapped <- listen (runMT m)
                        return (Just unwrapped)

tell 没问题,但我无法正确使用 listen 功能。在构造函数折纸的 1 1/2 天后,我能想到的最好的就是你在上面看到的那个:unwrapped 应该是 (Maybe a, w) 的元组,我想用 Maybe-Type 包裹起来,把整个东西放在一个空的 MonadWriter 中。

但编译器抱怨:

Occurs check: cannot construct the infinite type: a = Maybe a
    When generalising the type(s) for `listen'
    In the instance declaration for `MonadWriter w (MaybeT m)'

我错过了什么?

【问题讨论】:

    标签: typeclass monad-transformers haskell


    【解决方案1】:

    listen 具有类型签名

      m a -> m (a, w)
    

     MaybeT m a -> MaybeT m (a, w)
    

    但是MaybeT $ listen (runMT m) &gt;&gt;= return . Just 有类型签名

     MaybeT m a -> MaybeT m (Maybe a, w)
    

    因此引发了无限类型错误。您需要将 unwrapped :: (Maybe a, w) 转换为 Maybe (a, w) 才能继续:

    listen m = MaybeT $ do (val, wr) <- listen (runMT m)
                        case val of
                            Nothing -> return Nothing
                            Just x  -> return (Just (x, wr))
    

    (顺便说一句,在http://www.haskell.org/haskellwiki/New_monads/MaybeT 中有一个 MaybeT 的实现。)

    【讨论】:

    • @KennyTM:非常感谢!非常快速且非常精确!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-10
    • 1970-01-01
    相关资源
    最近更新 更多