0

在 scala 中使用单例对象进行隐式解析的最佳方法是什么?这对于Either自定义错误对象尤其常见。

在下面的代码示例中,方法返回包装在 IO 中的特定于应用程序的错误。错误由扩展的单例对象表示Throwable。此代码无法编译,因为 scala 正在寻找隐式 forAppSpecificError.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) {
4

1 回答 1

4

尝试显式指定类型参数

EitherT.left[Int][IO, Throwable](AppSpecificError.pure[IO])

或使用类型归属

EitherT.left[Int]((AppSpecificError: Throwable).pure[IO])
于 2020-08-04T13:44:14.350 回答