首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala中Ad多态性与参数多态性的差异

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

Stack Overflow用户
提问于 2018-08-27 18:07:13
回答 1查看 847关注 0票数 3

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

例如,集合中的head之类的方法显然是参数多态,因为用于在ListInt中获取头部的代码与任何其他列表中的代码相同。

代码语言:javascript
复制
List[T] {
    def head: T = this match {
        case x :: xs => x
        case Nil => throw new RuntimeException("Head of empty List.") 
    }
}

(不确定这是否是head的实际实现,但这并不重要)

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

代码语言:javascript
复制
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这样的方法,它们是参数化的,但是通过提供不同的功能,我们可以提供不同的实现。

代码语言:javascript
复制
List(1,2,3).filter(_ % 2 == 0)
// List(2)

像过滤器、地图等方法被认为是即席多态吗?为什么或者为什么不?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-27 20:21:34

filter on List是参数多态的一个例子。签名是

代码语言:javascript
复制
def filter(p: (A) ⇒ Boolean): List[A] 

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

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

map的完整签名是:

代码语言:javascript
复制
final def map[B, That]
  (f: (A) ⇒ B)
  (implicit bf: CanBuildFrom[List[A], B, That])
: That  

该方法依赖于隐式值(CBF)的存在,因此它具有ad多态性。但是,提供正确类型CBF的一些隐式方法实际上在AB类型中本身是参数多态的。因此,除非编译器能够在隐式范围内找到一些非常特殊的特殊构造(如CanBuildFrom[List[String], Int, BitSet] ),否则它迟早会回到如下的情况:

代码语言:javascript
复制
implicit def ahComeOnGiveUpAndJustBuildAList[A, B]
: CanBuildFrom[List[A], B, List[B]]

因此,我认为可以说,这是一种“混合参数-ad多态”,它首先试图在隐式范围内找到最合适的ad类型类CanBuildFrom[List[A], B, That],但最终回到普通的参数多态,并返回在AB中都是参数化多态的符合条件的CanBuildFrom[List[A], B, List[B]]-solution。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52044766

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档