Scala中Ad-hoc多态性与参数多态性的差异

Scala中Ad-hoc多态性与参数多态性的差异,scala,functional-programming,polymorphism,parametric-polymorphism,adhoc-polymorphism,Scala,Functional Programming,Polymorphism,Parametric Polymorphism,Adhoc Polymorphism,因此,我一直在搜索有关参数多态性和特殊多态性之间主要区别的文档,但我仍然有一些疑问 例如,集合中的head等方法显然是参数多态性,因为用于获取列表[Int]中的head的代码与任何其他列表中的相同 List[T] { def head: T = this match { case x :: xs => x case Nil => throw new RuntimeException("Head of empty List.") } }

因此,我一直在搜索有关
参数多态性
特殊多态性
之间主要区别的文档,但我仍然有一些疑问

例如,集合中的
head
等方法显然是参数多态性,因为用于获取列表[Int]中的head的代码与任何其他列表中的相同

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
在中间,我们有参数化的方法,比如filter,但是我们可以通过提供不同的函数来提供不同的实现

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

像filter、map等方法是否被认为是特殊多态性?为什么或为什么不?

列表
s上的方法
过滤器
,就是参数多态性的一个例子。签名是

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的隐式方法实际上本身在类型
A
B
中具有参数多态性。因此,除非编译器设法在隐式作用域中找到一些非常特殊的特殊特殊构造,如
CanBuildFrom[List[String],Int,BitSet]
,否则它迟早会返回到类似

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

因此,我认为可以说这是一种“混合参数即席多态性”,它首先尝试在隐式范围内找到最合适的即席类型类
CanBuildFrom[List[a],B]
,但最终返回到普通参数多态性,并返回一个适合所有人的
CanBuildFrom[List[a],B,列出[B]
-在
A
B

中都具有参数多态性的解决方案请参见下面的幻灯片,了解有关Scala中特殊多态性的详细介绍: