微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

monad-coroutine 协程的 MonadError 实例,用于任何挂起函子

如何解决monad-coroutine 协程的 MonadError 实例,用于任何挂起函子

是否可以为具有任意暂停 MonadErrormonad-coroutine Coroutine 编写 Functor 实例。

instance (MonadError e m,Functor s) => MonadError (Coroutine s m) where
    throwError = lift . throwError
    catchError c h = lift $ catchError (_ c) (_ . h)

什么东西可以钻进洞里?他们需要将 Coroutine s m r 转换为 m r,但我看不出这对于任意 s 是如何可能的。

解决方法

是的,这是可能的。 Coroutine 本质上与 FreeT 相同,后者有一个 MonadError 实例。

请注意,您的开始是错误的;您不能以 lift 开头。问题出现的时间比您想象的要早。

    catchError :: Coroutine f m a -> (e -> Coroutine f m a) -> Coroutine f m a
    catchError c f = lift _

==>

_ :: m a

即使您不必处理捕捉错误,也无法填补那个漏洞!

lift 确实不能胜任一般提升 catch 类函数的任务。

,

这种类型检查。不过,我不确定这是否合法。

{-# LANGUAGE FlexibleInstances,MultiParamTypeClasses,UndecidableInstances #-}

import Data.Bifunctor
import Control.Monad.Except
import Control.Monad.Coroutine

instance (MonadError e m,Functor s) => MonadError e (Coroutine s m) where
    throwError = lift . throwError
    Coroutine c `catchError` h = Coroutine $ fmap (first (fmap (`catchError` h))) c `catchError` (resume . h)

在英语中,其工作原理如下:首先,尝试运行 c 的单个步骤。三种情况是可能的:

  • 如果这引发错误,那么我们使用 h 处理错误并返回它所做的任何事情。
  • 如果成功并返回最终值,那么我们将返回相同的最终值。
  • 如果成功并返回一个暂停,那么我们还没有收到错误,但以后可能还会有,所以我们fmap (`catchError` h)在暂停函子上并返回它,递归这样我们有机会抓住以后再说吧。

编辑:我在看到 dfeuer 的回答或知道 FreeT 的实例之前写了这个,但那个实例与这个实例非常相似。这让我觉得这是合法的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?