3

parametric polymorphism因此,我一直在搜索有关and之间主要区别的文档 adhoc-polymorphism,但我仍然有一些疑问。

例如,像headCollections 中的方法,显然是参数多态性,因为用于获取 List[Int] 中的头部的代码与任何其他 List 中的相同。

List[T] {
    def head: T = this match {
        case x :: xs => x
        case Nil => throw new RuntimeException("Head of empty List.") 
    }
}

(不确定这是否是 head 的实际实现,但没关系)

另一方面,类型类被认为是临时多态性。因为我们可以提供不同的实现,限制在类型上。

trait Expression[T] {
    def evaluate(expr: T): Int
}

object ExpressionEvaluator {
  def evaluate[T: Expression](value: T): Int = implicitly[Expression[T]].evaluate(value)
}

implicit val intExpression: Expression[Int] = new Expression[Int] {
  override def evaluate(expr: Int): Int = expr
}

ExpressionEvaluator.evaluate(5)
// 5

在中间,我们有像过滤器这样的方法,它们是参数化的,但我们可以通过提供不同的功能来提供不同的实现。

List(1,2,3).filter(_ % 2 == 0)
// List(2)

过滤器、映射等方法是否被视为临时多态性?为什么或者为什么不?

4

2 回答 2

3

filters上的方法List是参数多态性的一个例子。签名是

def filter(p: (A) ⇒ Boolean): List[A] 

它对所有类型的工作方式完全相同A。由于它可以被任何类型参数A化,它是普通的参数多态。

像这样的方法map同时使用这两种类型的多态性。

的完整签名map是:

final def map[B, That]
  (f: (A) ⇒ B)
  (implicit bf: CanBuildFrom[List[A], B, That])
: That  

此方法依赖于隐式值(CBF-gizmo)的存在,因此它是临时多态性。但是,提供正确类型的 CBF 的一些隐式方法实际上在类型AB. 因此,除非编译器设法在隐式范围内找到一些非常特殊的临时构造,如 an CanBuildFrom[List[String], Int, BitSet],否则它迟早会退回到类似的东西

implicit def ahComeOnGiveUpAndJustBuildAList[A, B]
: CanBuildFrom[List[A], B, List[B]]

因此,我认为可以说这是一种“混合参数即席多态性”,它首先尝试CanBuildFrom[List[A], B, That]在隐式范围内找到最合适的即席类型类,但最终又回到普通的参数多态性,并且返回一个万能的解决方案,它在和CanBuildFrom[List[A], B, List[B]]中都是参数多态的。AB

于 2018-08-27T20:21:34.403 回答
0

有关 Scala 中的临时多态性的精彩介绍,请参阅以下幻灯片:https ://www.slideshare.net/pjschwarz/ad-hoc-polymorphism-using-type-classes-and-cats

在此处输入图像描述

于 2019-09-21T20:15:55.560 回答