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])
在 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])