[英]Difference between Ad-hoc polymorphism and Parametric polymorphism in Scala
所以,我一直在搜索关于parametric polymorphism
和adhoc-polymorphism
之间主要区别的文档,但我仍然有一些疑问。
例如,像集合中的head
方法显然是参数多态性,因为用于获取 List[Int] 中的 head 的代码与任何其他 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
在中间,我们有像 filter 这样参数化的方法,但是我们可以通过提供不同的函数来提供不同的实现。
List(1,2,3).filter(_ % 2 == 0)
// List(2)
过滤器、映射等方法是否被视为临时多态性? 为什么或者为什么不?
List
s上的方法filter
是参数多态的一个例子。 签名是
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)的存在,因此它是ad-hoc多态。 然而,提供正确类型的CBF的一些隐式方法实际上在类型A
和B
本身是参数化多态的。 因此,除非编译器设法在隐式作用域中找到一些非常特殊的ad-hoc构造,如CanBuildFrom[List[String], Int, BitSet]
,否则它迟早会回归到像
implicit def ahComeOnGiveUpAndJustBuildAList[A, B]
: CanBuildFrom[List[A], B, List[B]]
因此,我认为可以说它是一种“混合参数 - ad-hoc多态”,它首先尝试在隐式范围内找到最合适的特殊类型类CanBuildFrom[List[A], B, That]
,但最终回退到普通的参数多态,并返回一个一体的CanBuildFrom[List[A], B, List[B]]
在A
和B
参数化多态的解决方案。
有关 Scala 中的临时多态性的精彩介绍,请参阅以下幻灯片: https : //www.slideshare.net/pjschwarz/ad-hoc-polymorphism-using-type-classes-and-cats
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.