Скажет, у меня есть следующие функции:неявного преобразования в Монадическом для понимания в Scala
case class ErrA(msg: String)
case class ErrB(msg: String)
def doA(): Either[ErrA, Int] = Right(2)
def doB(): Either[ErrB, Int] = Right(3)
ErrA
и ErrB
являются несвязанными типами и фактически не объявлен в одном файле за пределами этого примера. Они не могут быть легко наследованы от общего типа.
Я хотел бы представить новый тип, который будет представлять оба вида ошибок:
sealed trait ErrAOrB
case class ErrAWrapper(e: ErrA) extends ErrAOrB
case class ErrBWrapper(e: ErrB) extends ErrAOrB
А затем написать следующую функцию с использованием для понимания:
def doAplusB(): Either[ErrAOrB, Int] =
for (a <- doA().right;
b <- doB().right) yield a + b
Есть ли способ, чтобы получить компилятор неявно конвертирует те конкретные типы Either
в общий тип Either[ErrAOrB, Int]
?
Например:
implicit def wrapA[T](res: Either[ErrA, T]): Either[ErrAOrB, T] = res.left.map(ErrAWrapper(_))
implicit def wrapB[T](res: Either[ErrB, T]): Either[ErrAOrB, T] = res.left.map(ErrBWrapper(_))
Но это не работает, потому что неявное преобразование будет применяться только к окончательному выражению в для понимания, а затем компилятор должен связать его с doA
и так типов ErrA
и ErrAOrB
не связаны друг с другом, что лучше всего сделать, чтобы сделать дженерики разумными - использовать Object
, который несовместим с ожидаемым типом.
Просто обратите внимание, что неявные представления не рекомендуются в Scala - вместо этого используйте неявный класс, поэтому он может быть smthng как 'doA(). Right.wrap'. Представьте, что люди читают ваш код и задаются вопросом, как «Либо [ErrA, Int]» стал «ErrAOrB»? Нет подсказки IDE, поэтому нет хорошего способа найти ваши «wrapA» implicits – dk14