EitherT 在返回子 class 时抛出编译错误
EitherT throws compilation error when returning child class
在下面的代码中,我使用了猫的 EitherT
class。它编译,但我被迫使用 Error
特性:
def isNeg(i:Int): Future[Either[Error,Int]] = Future {
我的意图是将函数声明为:
def isNeg(i:Int): Future[Either[IsPositive,Int]] = Future {
但是如果我使用 IsPositive
(函数的 Left
中返回的 class),Scala 会抛出一个编译错误。为什么不使用 IsPositive
编译?
import cats.data.EitherT
import cats.implicits._
trait Error
case class IsNegative() extends Error
case class IsPositive() extends Error
object HelloScala extends App {
def isPos(i:Int): Future[Either[IsNegative,Int]] = Future {
if (i>0)
Right(i)
else
Left(IsNegative())
}
def isNeg(i:Int): Future[Either[Error,Int]] = Future {
if (i<0)
Right(i)
else
Left(IsPositive())
}
def myFunction (i: Int) = {
val result = for {
ret <- EitherT(isPos(i)) // <-- compilation error, if IsPositive is used in isNeg
ret2 <- EitherT(isNeg(ret))
} yield ret2
println(result.value)
}
}
yield
是如何运作的?它被翻译成 flatMap
(参见 here)。因此,让我们尝试使用 flatMap
和 non-compilable 版本的显式类型重写您的案例:
val eithert1: EitherT[Future, IsNegative, Int] = EitherT(isPos(i))
def eithert2(ret: Int): EitherT[Future, IsPositive, Int] = EitherT(isNeg(ret))
eithert1.flatMap(ret => eithert2(ret)).map(ret2 => ret2)
现在你有哪些类型:
// What is expected (see `EitherT` type bounds in sources, I copied here)
// flatMap -> EitherT[F[_], A, B].flatMap[AA >: A, D](f: B => EitherT[F, AA, D])
// what you have:
// EitherT[Future, IsNegative, Int].flatMap[IsPositive >: IsNegative, Int](f: Int => EitherT[Future, IsPositive, Int])
你看:IsPositive >: IsNegative
,这是错误的。 IsNegative
的预期 super-type(Error
或 IsNegative
)
在下面的代码中,我使用了猫的 EitherT
class。它编译,但我被迫使用 Error
特性:
def isNeg(i:Int): Future[Either[Error,Int]] = Future {
我的意图是将函数声明为:
def isNeg(i:Int): Future[Either[IsPositive,Int]] = Future {
但是如果我使用 IsPositive
(函数的 Left
中返回的 class),Scala 会抛出一个编译错误。为什么不使用 IsPositive
编译?
import cats.data.EitherT
import cats.implicits._
trait Error
case class IsNegative() extends Error
case class IsPositive() extends Error
object HelloScala extends App {
def isPos(i:Int): Future[Either[IsNegative,Int]] = Future {
if (i>0)
Right(i)
else
Left(IsNegative())
}
def isNeg(i:Int): Future[Either[Error,Int]] = Future {
if (i<0)
Right(i)
else
Left(IsPositive())
}
def myFunction (i: Int) = {
val result = for {
ret <- EitherT(isPos(i)) // <-- compilation error, if IsPositive is used in isNeg
ret2 <- EitherT(isNeg(ret))
} yield ret2
println(result.value)
}
}
yield
是如何运作的?它被翻译成 flatMap
(参见 here)。因此,让我们尝试使用 flatMap
和 non-compilable 版本的显式类型重写您的案例:
val eithert1: EitherT[Future, IsNegative, Int] = EitherT(isPos(i))
def eithert2(ret: Int): EitherT[Future, IsPositive, Int] = EitherT(isNeg(ret))
eithert1.flatMap(ret => eithert2(ret)).map(ret2 => ret2)
现在你有哪些类型:
// What is expected (see `EitherT` type bounds in sources, I copied here)
// flatMap -> EitherT[F[_], A, B].flatMap[AA >: A, D](f: B => EitherT[F, AA, D])
// what you have:
// EitherT[Future, IsNegative, Int].flatMap[IsPositive >: IsNegative, Int](f: Int => EitherT[Future, IsPositive, Int])
你看:IsPositive >: IsNegative
,这是错误的。 IsNegative
的预期 super-type(Error
或 IsNegative
)