我试图围绕scalaz分离(\ /),但它还没有点击。请考虑以下事项:
scala> import scalaz._
import scalaz._
scala> def danger(i: Int): Int = throw new Exception("boom")
danger: (i: Int)Int
scala> \/-(1).map(danger)
java.lang.Exception: boom
at .danger(<console>:10)
at $anonfun$1.apply(<console>:12)
at $anonfun$1.apply(<console>:12)
at scalaz.$bslash$div.map(Either.scala:111)
... 43 elided
我天真的期望是,因为我在danger
内调用\/.map
,所以最后一个语句应该返回-\/(Exception("boom"))
,而不是炸毁。
我可以用
修复它scala> \/-(1).flatMap(i => \/.fromTryCatchNonFatal(danger(i)))
res4: scalaz.\/[Throwable,Int] = -\/(java.lang.Exception: boom)
但这会变得非常冗长和失控。是否有一种更简单的方法可以安全地链接带有析象的变换?
答案 0 :(得分:1)
理想情况下,danger
应该返回\/[A, B]
。如果您无法修改danger
的返回类型,请创建一个版本dangerousFn。这将使您能够以功能方式进行flatMap。
编辑:重新阅读OP的解决方案后,我正在使用fromTryCatchNonFatal
功能
import scalaz._
def danger(i: Int): Int = throw new Exception("boom")
val dangerousFn = (danger _).andThen(\/.fromTryCatchNonFatal)
for {
num <- \/-(1)
value <- dangerousFn(num)
} yield {
"This will never be reached"
}
输出:
import scalaz._
danger: danger[](val i: Int) => Int
res0: scalaz.\/[Throwable,String] = -\/(java.lang.Exception: boom)