如何将 Maybe-Transformer MaybeT 制作为 MonadWriter 的实例?

发布于 2024-08-30 20:44:28 字数 1249 浏览 3 评论 0原文

我正在尝试构建一个 MaybeT-Transformer Monad,基于 Real World HaskellMonad 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 天的构造函数折纸后,我能想到的最好的就是您在上面看到的:展开应该是一个 (也许 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)'

我错过了什么?

I am trying to build a MaybeT-Transformer Monad, based on the example in the Real World Haskell, Chapter 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)

This works fine, but now I want to make MaybeT an instance of MonadWriter:

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

The tell is ok, but I can't get the listen function right. The best I could come up with after 1 1/2 days of constructor origami is the one you see above: unwrapped is supposed to be a tuple of (Maybe a, w), and that I want to wrap up in a Maybe-Type and put the whole thing in an empty MonadWriter.

But the compiler complains with:

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)'

What am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

亣腦蒛氧 2024-09-06 20:44:28

listen 具有类型签名

  m a -> m (a, w)

,即

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

But MaybeT $listen (runMT m) >>= return 。只是 具有类型签名,

 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))

顺便说一句,有一个 MaybeT 的实现 < a href="http://www.haskell.org/haskellwiki/New_monads/MaybeT" rel="noreferrer">http://www.haskell.org/haskellwiki/New_monads/MaybeT。)

listen has type signature

  m a -> m (a, w)

i.e.

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

But MaybeT $ listen (runMT m) >>= return . Just has type signature

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

so the infinite type error is raised. You need to convert that unwrapped :: (Maybe a, w) into a Maybe (a, w) to proceed:

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

(BTW, there is an implementation of MaybeT in http://www.haskell.org/haskellwiki/New_monads/MaybeT.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文