Я пытаюсь сделать такую функцию:
def foo(x: Either[String, Int]) = x match {
case Left(s) => Left("foo:" + s)
case Right(n) => Right(n+1)
}
Это работает, но я ищу способ убедить вызывающего, что результат всегда будет того же типа, что и ввод — если ввод «Левый», вы получите «Левый» обратно, если он был «Правый», вы получите «Правый».
Может ли кто-нибудь придумать изящный трюк, который я мог бы использовать для этого?
Я знаю, что могу это сделать:
def foo[T <: Either[String, Int]](x: T): T = (x match {
case Left(s) => Left("foo:" + s)
case Right(n) => Right(n+1)
}).asInstanceOf[T]
... но приведение в конце уродливое :( Это объявление будет абстрактным членом базового трейта, который нужно будет переопределить нескольким реализациям "плагинов", и я не хочу, чтобы все они должны сделать эту вещь типа литья.
Я также мог бы сделать две отдельные функции fooString
и fooInt
... но этого я хотел бы избежать по некоторым соображениям, характерным для конкретного API, над которым я работаю.
Любые другие идеи?