因此,我一直在搜索关于parametric polymorphism和adhoc-polymorphism之间的主要区别的文档,但我仍然有一些疑问。
例如,集合中的head之类的方法显然是参数多态,因为用于在ListInt中获取头部的代码与任何其他列表中的代码相同。
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)像过滤器、地图等方法被认为是即席多态吗?为什么或者为什么不?
发布于 2018-08-27 20:21:34
filter on 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)的存在,因此它具有ad多态性。但是,提供正确类型CBF的一些隐式方法实际上在A和B类型中本身是参数多态的。因此,除非编译器能够在隐式范围内找到一些非常特殊的特殊构造(如CanBuildFrom[List[String], Int, BitSet] ),否则它迟早会回到如下的情况:
implicit def ahComeOnGiveUpAndJustBuildAList[A, B]
: CanBuildFrom[List[A], B, List[B]]因此,我认为可以说,这是一种“混合参数-ad多态”,它首先试图在隐式范围内找到最合适的ad类型类CanBuildFrom[List[A], B, That],但最终回到普通的参数多态,并返回在A和B中都是参数化多态的符合条件的CanBuildFrom[List[A], B, List[B]]-solution。
https://stackoverflow.com/questions/52044766
复制相似问题