2

私は、ビジネス上の意味を持つカスタム例外をスローしたり、(動的クラスのインスタンス化によって) 異なる結果タイプを返すことができるメソッドを持つ、基礎となる Java API を持っています。メソッドが結果を返す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ますか?

4

1 に答える 1

1

fneed parameter による呼び出しとしてパラメータを使用:

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)
于 2016-06-10T13:24:40.117 に答える