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)
}
A
和B
,我们需要implicit ev: A1 <:< Either[C, B1]
A1 >: A, B1 >: B
。 A1 <: Either[C, B1]
conforms[A1]
和conforms[Either[C, B1]]
如果直到现在我仍然是对的,那么A1
和B1
似乎有很多选择,只要它们超出下限A
和B
。所以我想知道scala如何为我们提供A1
和Either[C, B1]
(以及它们是什么),以便我们获得隐式conforms
以促进<:<
完成其断言工作A1 <: Either[C, B1]
。
P.S。
我认为这个问题与我的另一个问题“joinLeft [A1 >: A, B1 >: B, C]… why are type constraint A1 >: A and B1>: B necessary?”有些相关。如果有人也可以看一下,我将不胜感激。
答案 0 :(得分: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来解析,它给出了具有最高优先级的隐式。