【问题标题】:Higher kinded types vs generics高级类型与泛型
【发布时间】:2018-06-11 09:56:01
【问题描述】:

我正在阅读有关 Scala 中更高种类的类型的信息,但我无法理解下划线的使用。

例如:

trait Functor[F[_]] {
  def map[A, B](fa: F[A])(f: A => B) : F[B]
}

val listFunctor = new Functor[List] {
  override def map[A, B](fa: List[A])(f: A => B) = fa.map(f)
}

listFunctor.map(List(1,2,3))(_ + 3)

如果我在特征中使用参数化类型 A,我会得到相同的结果:

trait Functor2[F[A]] {
  def map[A, B](fa: F[A])(f: A => B) : F[B]
}

val listFunctor2 = new Functor2[List] {
  override def map[A, B](fa: List[A])(f: A => B) = fa.map(f)
}

listFunctor2.map(List(1,2,3))(_ + 3)

这两个例子有显着差异吗?

【问题讨论】:

  • 在您的第二个示例中,您的 A 来自 map[A, B]F[A] 中定义的一个是不同的。它只是一个占位符。并且不能在签名之外使用。通常,更高种类的类型只是将另一种类型作为参数的类型。语法并不那么重要。

标签: scala higher-kinded-types


【解决方案1】:

这两种表达Functor2 是通过类型构造函数参数化这一事实的方式没有区别。如果您注意到,在后一种情况下,A 只是一个占位符,因为它没有在其他地方声明。

我通常更喜欢使用F[_] 语法,因为它阐明了我们需要一个类型构造函数,并且我们在类中引用的占位符和类型之间的命名不会意外重叠:在后一种情况下,即使它们happen 引用相同的类型参数,构造函数签名中的Amap 方法签名中的A 之间没有强制约束,这也可能导致一些混淆了这两个 A 的性质以及它们之间的关系。

【讨论】:

    猜你喜欢
    • 2016-04-05
    • 2010-09-20
    • 2013-10-11
    • 1970-01-01
    • 2015-04-28
    • 1970-01-01
    • 2012-10-19
    • 2018-06-12
    • 2017-07-01
    相关资源
    最近更新 更多