关于joinLeft的类型约束和规范



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)
}
  • 已知AB,我们需要一个implicit ev: A1 <:< Either[C, B1]
    1. 满足约束A1 >: A, B1 >: B
    2. 规范A1 <: Either[C, B1]

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

如果我现在仍然是正确的,对我来说,A1B1似乎有很多选择,只要它们超出了AB的下界。所以我想知道scala如何给我们A1Either[C, B1](以及它们是什么),以便我们得到隐式conforms,以促进<:<完成断言A1 <: Either[C, B1]的工作。

注:
我认为这个问题有点关系到我的另一个"joinLeft [A1>: A, B1>: B, C]…为什么类型约束A1>: A和B1>: B是必要的?"。如果有人也能看一下,我将不胜感激。

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

的值。
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给出了最高优先级的隐式。

相关内容

  • 没有找到相关文章

最新更新