猫嵌套 Xor catchOnly leftMap
Cats nested Xor catchOnly leftMap
我有一个底层 java api,它的方法可以抛出具有业务意义的自定义异常,或者可以 return 不同的结果类型(通过动态 class实例化)。在方法 return 的结果中,我有一个 A Xor B
,其中 A 是错误类型,但我想使用 Xor.catchOnly[CustomException]
和 leftMap 方法将异常转换为 A。
import cats.data.Xor
import scala.reflect.ClassTag
def zor[E >: Null <: Throwable : ClassTag, A , B](f: A Xor B)(g: E => A) : A Xor B = {
Xor.catchOnly[E]{f}.leftMap(g).flatMap(identity)
}
object CustomExceptions {
class XYZException extends RuntimeException()
class FooException extends XYZException
class BarException extends XYZException
def exceptionToError[E <: XYZException] = (e: E) => {
e.toString
}
}
object Xorish {
import CustomExceptions._
type OUT = String Xor Int
def xorCatchOnlyString(f: => String Xor Int): String Xor Int =
Xor.catchOnly[XYZException](f).leftMap(exceptionToError).flatMap(identity)
def doIt(i: Int): OUT = zor{
if (i < 0) throw new FooException()
else if (i < 10) throw new BarException()
else if (i < 20) Xor.left("Splat")
else Xor.right(i)
} (exceptionToError)
def doItSoItWorks(i: Int): OUT = xorCatchOnlyString{
if (i < 0) throw new FooException()
else if (i < 10) throw new BarException()
else if (i < 20) Xor.left("Splat")
else Xor.right(i)
}
}
我可以通过 xorCatchOnlyString
调用来做到这一点,但我试图概括并提出 zor
但这会抛出异常,而不是像我希望的那样捕获它。有什么方法可以按照 zor
做我想做的事吗?
以参数f
作为需要参数的调用:
import cats.data.Xor, cats.implicits._
def zor[E >: Null <: Throwable : ClassTag, A , B](f: => A Xor B)(g: E => A) : A Xor B =
Xor.catchOnly[E]{f}.leftMap(g).flatten
class XYZException extends RuntimeException()
def f: String Xor Int = throw new RuntimeException("boom")
def g: String Xor Int = throw new XYZException
zor[RuntimeException, String, Int](f)(_.getMessage)
// Xor[String,Int] = Left(boom)
zor[XYZException, String, Int](g)(_ => "xyz")
// Xor[String,Int] = Left(xyz)
我有一个底层 java api,它的方法可以抛出具有业务意义的自定义异常,或者可以 return 不同的结果类型(通过动态 class实例化)。在方法 return 的结果中,我有一个 A Xor B
,其中 A 是错误类型,但我想使用 Xor.catchOnly[CustomException]
和 leftMap 方法将异常转换为 A。
import cats.data.Xor
import scala.reflect.ClassTag
def zor[E >: Null <: Throwable : ClassTag, A , B](f: A Xor B)(g: E => A) : A Xor B = {
Xor.catchOnly[E]{f}.leftMap(g).flatMap(identity)
}
object CustomExceptions {
class XYZException extends RuntimeException()
class FooException extends XYZException
class BarException extends XYZException
def exceptionToError[E <: XYZException] = (e: E) => {
e.toString
}
}
object Xorish {
import CustomExceptions._
type OUT = String Xor Int
def xorCatchOnlyString(f: => String Xor Int): String Xor Int =
Xor.catchOnly[XYZException](f).leftMap(exceptionToError).flatMap(identity)
def doIt(i: Int): OUT = zor{
if (i < 0) throw new FooException()
else if (i < 10) throw new BarException()
else if (i < 20) Xor.left("Splat")
else Xor.right(i)
} (exceptionToError)
def doItSoItWorks(i: Int): OUT = xorCatchOnlyString{
if (i < 0) throw new FooException()
else if (i < 10) throw new BarException()
else if (i < 20) Xor.left("Splat")
else Xor.right(i)
}
}
我可以通过 xorCatchOnlyString
调用来做到这一点,但我试图概括并提出 zor
但这会抛出异常,而不是像我希望的那样捕获它。有什么方法可以按照 zor
做我想做的事吗?
以参数f
作为需要参数的调用:
import cats.data.Xor, cats.implicits._
def zor[E >: Null <: Throwable : ClassTag, A , B](f: => A Xor B)(g: E => A) : A Xor B =
Xor.catchOnly[E]{f}.leftMap(g).flatten
class XYZException extends RuntimeException()
def f: String Xor Int = throw new RuntimeException("boom")
def g: String Xor Int = throw new XYZException
zor[RuntimeException, String, Int](f)(_.getMessage)
// Xor[String,Int] = Left(boom)
zor[XYZException, String, Int](g)(_ => "xyz")
// Xor[String,Int] = Left(xyz)