我正在阅读Scala中更高级的kinded类型,我不能围绕使用下划线。
例如:
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)
两个例子之间是否存在显着差异?
答案 0 :(得分:4)
这两种方式之间没有区别,表达Functor2
在类型构造函数上进行参数化的事实。如果您注意到,在后一种情况下,A
只是一个占位符,因为它尚未在其他地方声明。
我通常更喜欢使用F[_]
语法,因为它阐明了我们需要一个类型构造函数,并且我们在类中引用的占位符和类型之间的命名中没有意外重叠:在后一种情况下,甚至虽然它们发生以引用相同的类型参数,但构造函数签名中的A
与A
方法签名中的map
之间没有强制约束,这也可能导致一些关于两个A
的性质以及它们如何相互关联的混淆。