协变类型 E 在 A 型 => 返回误差中以逆变位置出现。值 f 的错误 [E,B]

  • 本文关键字:位置 错误 类型 误差 返回 scala
  • 更新时间 :
  • 英文 :


我有这个定义:

sealed trait Error[+E, +A] {
  final def map[B](f: A => B): Error[E, B] = {
    this match {
      case Ok(a) => Ok(f(a))
      case Fail(e) => Fail(e)
    }
  }
  final def flatMap[B](f: A => Error[E, B]): Error[E, B] = {
    this match {
      case Ok(a) => f(a)
      case Fail(e) => Fail(e)
    }
  }
}
object Error {
  final case class Ok[A](a: A) extends Error[Nothing, A]
  final case class Fail[E](e: E) extends Error[E, Nothing]
}

这不会编译此错误:

Error.scala:12: covariant type E occurs in contravariant position in type A => returnerror.Error[E,B] of value f
  final def flatMap[B](f: A => Error[E, B]): Error[E, B] = {
                       ^
one error found

我不明白为什么。你能解释一下为什么这不编译吗?谢谢

我将稍微

简化示例,以使其更易于阅读。

想象一下,你有这样的trait,让我们假设这样的声明是合法的:

trait Error[+E]  {
  def someMethod (f: String => Error[E])  // actually illegal
}

和实施

class ErrorString extends  Error[String]  {
  def someMethod (f: String => Error[String]) = {
    val someVar: Error[String] = f("Somestring")
  }
}
class ErrorInt extends  Error[Int]  {
    ...
} 

由于E是协变的,我们可以将Error[String]视为Error[Any]的子类型,因此我们可以编写以下

val anyError: Error[Any] = new ErrorString()

然后将String => Error[Int]函数作为参数传递给someMethod

val intErrorReturnFunction: String => Error[Any] = (k) => new ErrorInt
anyError.someMethod(intErrorReturnFunction) // actually illegal

但是由于anyError在后台仍然有类型 Error[String] 意味着我们正尝试String => Error[Int]函数传递给带有String => Error[String]参数的方法。

所以最后我们会有这样的东西

 val someVar: Error[String] = f("Somestring"):Error[Int]

最新更新