scala 在`.delay`或`.map`中引发异常的cats-effect中预期行为

w7t8yxp5  于 2023-06-23  发布在  Scala
关注(0)|答案(1)|浏览(187)

在PR审查期间,我被要求将Sync[F].delay替换为Sync[F].catchNonFatal,因为可能会抛出异常。
这确实有效:

scala> Sync[IO].delay(throw new Exception).recover{ case t: Throwable => 42 }.unsafeRunSync
res10: Int = 42

不确定这种行为是否特定于IO,我也能够找到相应的法律,说它实际上是预期的,但我在主要的cats-effect文档中找不到关于API中自动处理异常的提及。
有谁知道猫效应w.r.t.的原理和预期行为。在.delay.map.flatMap中抛出异常?

vlju58qv

vlju58qv1#

正如您所发现的,delay捕获异常是有法律保证的--这是API的一个重要部分,如果不是这样,就很难使用。
至于mapflatMap,没有基于法律的保证,这些方法可以捕获异常-这些方法在FunctorFlatMap类型类中定义,而不是cats-effect。它们期望纯函数,并且捕获抛出的异常不是引用透明的。
然而在实践中,特别是对于IO,异常 * 被 * 捕获为IO类型契约的一部分。但是依赖于它来编写泛型代码从来都不是理想的。
所以,不要写代码像

IO(blah).map(a => mightThrow(a))

而是写

IO(blah).flatMap(a => Either.catchNonFatal(mightThrow(a)).liftTo[IO])

理想情况下,mightThrow方法将返回一个Either,而不是抛出,如果它没有副作用的话

相关问题