Как лучше всего заставить неявное разрешение в scala работать с одноэлементными объектами? Это особенно характерно для Either
и настраиваемых объектов ошибок.
В приведенном ниже примере кода метод возвращает специфичную для приложения c ошибку, заключенную в IO. Ошибка представлена одноэлементным объектом, расширяющим Throwable
. Этот код не компилируется, потому что scala ищет неявное выражение для AppSpecificError.type
вместо Throwable
.
Можно поместить все в переменные с указанным типом, но это выглядит странно. Это довольно распространенный случай, как лучше всего его решить?
import cats.data.EitherT
import cats.effect.IO
import cats.implicits._
import scala.util.Random
object EitherTest {
case object AppSpecificError extends Throwable
def random: IO[Boolean] = {
IO(Random.nextBoolean())
}
def appMethod(flag: Boolean): EitherT[IO, Throwable, Int] = {
for {
flag <- EitherT.right(random)
result <- if (flag) {
EitherT.left[Int](AppSpecificError.pure[IO]) // compilation error here
} else {
EitherT.right[Throwable](10.pure[IO])
}
// can be more computations here
} yield result
}
def main(args: Array[String]): Unit = {
appMethod(true).value.unsafeRunSync() match {
case Right(s) => println("Success")
case Left(error) => println(error)
}
}
}
Error:(18, 14) type mismatch;
found : cats.data.EitherT[cats.effect.IO,_1,Int] where type _1 >: EitherTest.AppSpecificError.type <: Throwable
required: cats.data.EitherT[cats.effect.IO,Throwable,Int]
Note: _1 <: Throwable, but class EitherT is invariant in type A.
You may wish to define A as +A instead. (SLS 4.5)
result <- if (flag) {