簡體   English   中英

協變類型E出現在類型A => returnerror.Error [E,B]值f的相反位置

[英]covariant type E occurs in contravariant position in type A => returnerror.Error[E,B] of value f

我有這個定義:

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]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM