Scala ZIO错误通道是什么?如何获得输入内容的感觉?

Scala ZIO错误通道是什么?如何获得输入内容的感觉?,scala,functional-programming,io-monad,zio,bifunctor,Scala,Functional Programming,Io Monad,Zio,Bifunctor,ZIO()是一个scala框架,其核心是ZIO[R,E,a]数据结构,其站点提供了三个参数的以下信息: ZIO ZIO[R,E,A]数据类型有三个类型参数: R-环境类型。该效果需要类型为R的环境。如果此类型参数为Any,则表示该效果不存在 要求,因为您可以使用任何值运行效果(对于 例如,单位值()) E-故障类型。如果值类型为E,效果可能会失败。某些应用程序将使用可丢弃的。如果此类型参数为 无,表示效果不能失败,因为没有 类型为Nothing的值 A-成功类型。如果值类型为a,效果可能会成功

ZIO
()是一个scala框架,其核心是
ZIO[R,E,a]
数据结构,其站点提供了三个参数的以下信息:

ZIO

ZIO[R,E,A]
数据类型有三个类型参数:

  • R
    -环境类型
    。该效果需要类型为
    R
    的环境。如果此类型参数为
    Any
    ,则表示该效果不存在 要求,因为您可以使用任何值运行效果(对于 例如,单位值
    ()
  • E
    -故障类型
    。如果值类型为
    E
    ,效果可能会失败。某些应用程序将使用可丢弃的
    。如果此类型参数为
    ,表示效果不能失败,因为没有 类型为Nothing的值
  • A
    -成功类型
    。如果值类型为
    a
    ,效果可能会成功。如果此类型参数为
    单位
    ,则表示效果不会产生任何影响 有用的信息,如果它是
    ,则表示效果运行 永远(或直到失败)
很容易得到
A
是什么:它是函数在标称情况下返回的值,也就是为什么我们要对函数进行编码。
R
是一种依赖注入-一个有趣的话题,但是我们可以忽略它来使用
ZIO
,总是将其设置为
Any
(实际上,库中有一个
IO[E,a]=ZIO[Any,E,a]
别名)

因此,它仍然是
E
类型,用于错误(著名的错误通道)。我粗略地了解到,
IO[E,A]
是一种
或者[E,A]
,但是处理的是效果(这很好)


我的问题是:为什么我应该在应用程序中的任何地方使用错误通道,以及如何决定应该在错误通道中使用什么?

1/为什么使用错误通道进行效果管理?

作为一名开发人员,您最困难的任务之一是确定什么是错误,什么不是应用程序中的错误,或者更准确地说,发现故障模式:什么是标称路径(即代码的目标),什么是应用程序以后可以以某种方式处理的预期错误,以及应用程序无法处理的意外错误。这个问题没有明确的答案,这取决于应用程序和上下文,因此需要由开发人员自己来决定

但最困难的任务是构建一个遵守承诺(你的承诺,因为你选择了什么是错误,什么是名义路径)的应用程序,这并不奇怪,因此用户、管理员、,而dev——包括两周后的futur you——知道在大多数情况下代码都做了什么,而不必猜测,也不需要机构来适应这种行为,包括响应错误

这很难,你需要一个系统的过程来处理所有可能的案例,而不必去做

IO
bi-monad(因此
ZIO
)中的错误通道可以帮助您完成该任务:
IO
monad可以帮助您跟踪影响,而影响是大多数错误的来源,错误通道可以明确指出可能的错误情况,因此,如果可以的话,应用程序的其他部分有机构来处理它们您将能够通过明确的故障模式以纯粹、一致、可组合的方式管理效果。 此外,在
ZIO
的情况下,您可以非常轻松地导入非纯代码,如遗留java:

val pure = ZIO.effect(someJavaCodeThrowingException)
2/如何选择错误?

因此,错误通道提供了一种对
what if?
问题的答案进行编码的方法,供未来开发人员处理该代码。“如果数据库关闭怎么办?”“有一个
DatabaseConnectionError
”。 但是对于您的用例,对于当前的应用程序级别,所有的
如果
都不一样,那该怎么办呢。“如果找不到用户怎么办?”-啊,这可能是一个完全预期的低“存储库”级别的答案(如“查找”没有找到任何内容),也可能是另一个级别的错误(如在验证用户的过程中,它应该真的存在)。在第一种情况下,您可能不会使用错误通道:它是标称路径,有时您找不到东西。在第二种情况下,您可能会使用错误通道(
UserNotFoundError

正如我们所说,错误通道中的错误通常是针对应用程序中可能需要处理的
what if
问题,而不是在该功能级别。
DatabaseConnectionError
的第一个示例可能在应用程序中更高,并导致用户消息“请再试一次”和发送给系统管理员的通知电子邮件(“快速,查看一下,如果这里有问题”)。
UserNotFoundError
可能会在登录表单中作为用户的错误消息进行管理,例如“登录或密码错误,请重试或使用该过程恢复凭据”

因此,这些情况(名义误差和预期误差)是容易的部分。但是有一些
what if
问题您的应用程序,无论级别如何,都不知道如何回答。“如果我试图分配那个对象时出现内存异常怎么办?”我没有任何线索,事实上,即使我有线索,那也超出了我要为那个应用程序处理的范围。所以这些错误不会进入错误通道。我们称之为失败,当它们发生时,我们会使应用程序崩溃,因为应用程序现在可能处于未知的、危险的僵尸状态

同样,这个选择(标称路径/错误通道/故障)是您的选择:两个应用程序可以做出不同的选择。例如,一个一次性数据处理应用程序然后丢弃它,它很可能会处理所有非标称路径