首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在哪里使用`ApplicativeError`而不是`Either`?

在哪里使用`ApplicativeError`而不是`Either`?
EN

Stack Overflow用户
提问于 2020-04-28 22:57:03
回答 1查看 605关注 0票数 4

ApplicativeError[F,E] + F[A],也有Either[E, A]。它们都传达了这样的信息:函数可能会因为E而失败,或者会因为A而成功,但我不确定它们向客户端传达的关于处理错误的预期方式的不同信息:

代码语言:javascript
运行
复制
def f1[F[_]: Applicative[F]]: F[Either[E, A]]
def f2[F[_]: ApplicativeError[F,E]]: F[A]

我理解f1的意思是:客户端负责错误处理。但是关于如何处理错误,f2对客户端意味着什么呢?

EN

回答 1

Stack Overflow用户

发布于 2020-04-28 23:21:32

ApplicativeError[F, E]假设E的类型以某种方式编码在F中,并且您只能创建ApplicativeError[F, E]的实例,因为对于这个特定的F,使用错误E是有意义的。示例:

  • ApplicativeError[Task, Throwable] - Task使用Throwable作为错误通道,因此将Throwable公开为错误代数是有意义的。事实上,来自Cats Effect的Sync[F]实现了MonadError[F, Throwable],而后者又实现了ApplicativeError[F, Throwable] -许多Cats的类型类假设您只处理Throwable
  • ApplicativeError[Task[Either[E, *]], E] -在这样的组合中,您将在类型F的特定定义以及E参数中都有E -这对于所有类型的双函数都是典型的:Task[Either[E, *]]EitherT[Task, E, *]、ZIO的IO[E, A],等等<代码>H225<代码>F226

接口ApplicativeError[F, E]本身并不能处理错误。但是它公开了一些方法:

  • raiseError[A](e: E): F[A] -它创建了一个error
  • handleErrorWith[A](fa: F[A])(f: (E) ⇒ F[A]): F[A] -处理

这样你就可以告诉它如何处理它。

两者都不需要任何关于错误性质的假设就可以工作,而F其他的是Applicative,它可能会失败。如果只使用F和type类,则可以使用这些方法从错误中恢复。如果您知道调用站点上F的确切类型(因为它被硬编码为TaskIOCoeval等),您可以直接使用恢复方法。

主要区别在于,结果F[Either[E, A]]不会告诉调用者E应该被视为失败。F[A]告诉我们可能只有A成功的值。另外,一个需要Applicative,而另一个需要ApplicativeError,所以创建一个值所需的“能力”是不同的-如果你看到ApplicativeError,即使结果中没有E,你可以假设该方法可能会失败,因为它需要更强大的类型类。

但它当然不是一成不变的,它主要是表达意图,因为在任何你有F[A]的地方,你都可以使用ApplicativeError[F, E]F[Either[E, A]]之间进行转换(甚至有像attempt[A](fa: F[A]): F[Either[E, A]]fromEither[A](x: Either[E, A]): F[A]这样的方法)。所以在你的应用程序的一部分,你可以使用带有E代数的F[A],但是还有一个使用Either[E, A] => B的纯函数,你想要使用它--然后你可以转换,映射,如果需要的话,还可以转换回来。

这主要是关于表达意图,因为两者在道德上是平等的。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61483271

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档