0

joinLeft定义为:

abstract class Either[+A, +B]

def joinLeft[A1 >: A, B1 >: B, C](implicit ev: A1 <:< Either[C, B1]):
    Either[C, B1] = this match {
    case Left(a)  => a
    case Right(b) => Right(b)
}
  • 有了已知的Aand B,我们需要一个implicit ev: A1 <:< Either[C, B1]that
    1. 满足约束A1 >: A, B1 >: B
    2. 物化A1 <: Either[C, B1]

  • 为此,我们需要隐式 conforms[A1]conforms[Either[C, B1]]

如果直到现在我仍然是正确的,那么在我看来,A1只要B1它们超出下限AB. 所以我想知道 scala 如何给我们A1Either[C, B1](以及它们是什么),以便我们隐含conforms以促进<:<完成断言的工作A1 <: Either[C, B1]

PS
我认为这个问题与我的另一个问题有点相关“ joinLeft [A1 >: A, B1 >: B, C]... 为什么类型约束 A1 >: A and B1>: B 是必要的? ”。如果有人也可以看看它,我将不胜感激。

4

1 回答 1

1

你是对的,有很多选择。一般来说,泛型方法的类型推断使用参数来确定泛型参数的值

def myMethod[A](aList:List[A])

但是,这不是使用泛型参数类型推断的唯一方法。值得注意的是,类型参数可以是:

  • 明确的
  • 使用预期结果类型确定

在这种情况下,由于无法从参数中确定泛型类型参数(因为没有显式参数),您通常将方法的结果分配给类型化变量,或者在显式返回的方法末尾使用它类型。

你可能会问自己 A1 将如何解决,这是一个非常有趣的问题。实际上 A1 不存在于输入类型中,也不存在于输出类型中。它有什么用?

答案在以下定义中,来自Predef.scala

@implicitNotFound(msg = "Cannot prove that ${From} <:< ${To}.")
  sealed abstract class <:<[-From, +To] extends (From => To) with Serializable

因为在方法中<:<是逆变的From

def joinLeft[B1 >: B, C](implicit ev: A <:< Either[C, B1]):
    Either[C, B1] = this match {
    case Left(a)  => a
    case Right(b) => Right(b)
}

将无法正确处理 A 上的子类化。这就是为什么您需要一个额外的泛型类型参数 A1 的原因,Scala 编译器通过使用 A1 来解决这个问题,该 A1 赋予隐式最高优先级。

于 2013-04-15T11:52:56.727 回答