Scala 单例对象和隐式解析

Scala singleton objects and implicit resolution

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

在下面的代码示例中,方法 returns 包含在 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) {

尝试明确指定类型参数

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

或使用类型归属

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