我们可以通过参数调用scala函数多态,而不需要无形

时间:2015-12-09 21:31:37

标签: scala shapeless

我正在谈论这个问题(而且只涉及参数多态性):

def fun1[T](s: Set[T]): Option[T] = s.headOpton

我在一些地方看到过,人们称这是原始标量T周围的多态函数的一个例子 - 就像在无形Set ~> Option中一样。

但我不明白为什么我们可以称之为多态。即使我们似乎能够通过Set[Int]Set[String]实际上fun1[Int]fun1[String]两个不同的功能。我想我可以声称,因为fun1的eta扩展是错误的,并没有给我们想要的东西:

scala> fun1 _
res0: Set[Nothing] => Option[Nothing] = <function1>

我们需要在扩展时提及类型:

scala> fun1[Int]_
res1: Set[Int] => Option[Int] = <function1>

我正在努力学习无形,我试着将它与原始的scala进行比较 - 这就是问题的来源。我理解正确吗?

1 个答案:

答案 0 :(得分:2)

fun1实施不依赖于T类型,因此它通常是

  

使用参数多态,函数或数据类型都可以   一般地写,以便它可以在没有相同的情况下处理值   取决于他们的类型。

(来源Wikipedia

我同意你提到fun1[Int]fun1[String]“是两个不同的功能”。这些都是采用“具体类型”:

  

参数多态是指值的类型包含的时间   一个或多个(不受约束的)类型变量,以便值可以   采用任何用这些变量代替的结果   具体类型。

(来源Haskell wiki

在@Travis和@Miles评论后

编辑

正如Travis清楚解释的那样,我们可以在“普通scala”中使用多态方法,但不能在多态函数中使用多态方法。在this article Miles中使用Poly实现了这个问题中提到的多态函数:

object headOption extends PolyFunction1[Set, Option] {
  def apply[T](l: Set[T]): Option[T] = l.headOption
}

scala> headOption(Set(1, 2, 3))
res2: Option[Int] = Some(1)