bet*_*ess 6 scala scala-cats cats-effect
在PR审查期间,我被要求替换Sync[F].delay,Sync[F].catchNonFatal因为可能会抛出异常.
这确实有效:
scala> Sync[IO].delay(throw new Exception).recover{ case t: Throwable => 42 }.unsafeRunSync
res10: Int = 42
Run Code Online (Sandbox Code Playgroud)
不确定这种行为是否具体IO,我也能找到相应的法律说它实际上是预期的,但我在主要的cat-effect文档中找不到关于API中异常的自动处理的提及.
有谁知道的理由和预期的行为,然后猫效应WRT异常抛出.delay或.map或.flatMap?
正如您所发现的,它受到捕获异常的法律的保证delay- 这是 API 的重要组成部分,如果不是这样,它将很难使用。
至于map和flatMap,没有基于法律的保证在这些方法中捕获异常 - 这些方法是在 和Functor类型FlatMap类中定义的,而不是 cats-effect 中。他们期望纯函数,并且捕获抛出的异常不是引用透明的。
然而在实践中,IO具体而言,异常被捕获为IO类型契约的一部分。但依赖它来实现通用代码从来都不是理想的选择。
所以,不要写这样的代码
IO(blah).map(a => mightThrow(a))
Run Code Online (Sandbox Code Playgroud)
而是写
IO(blah).flatMap(a => Either.catchNonFatal(mightThrow(a)).liftTo[IO])
Run Code Online (Sandbox Code Playgroud)
理想情况下,如果没有副作用,该mightThrow方法将返回而不是抛出Either