2

这个签名声明了更高种类的类型:

case class MyContainer[A, M[_]](el: M[A])

现在,我可以创建它的实例:

scala> val mc1 = MyContainer[Int, Option](Some(3))
mc1: MyContainer[Int,Option] = MyContainer(Some(3))

我也可以声明MyContainer为:

case class MyContainer[A, M[A]](el: M[A])

它产生与以下相同的实例mc1

mc1: MyContainer[Int,Option] = MyContainer(Some(3))

这些方法有什么区别,什么时候应该使用?

4

1 回答 1

4

根据语言规范(§4.4 类型参数),这些是等价的:

[M[X], N[X]]
[M[_], N[_]] // equivalent to previous clause

本段描述了此语法背后的原因:

高阶类型参数(类型参数的类型参数t)仅在其紧邻的参数子句(可能包括更深嵌套级别的子句)和t. 因此,它们的名称只能与其他可见参数的名称成对不同。由于高阶类型参数的名称因此通常是不相关的,它们可以用 a 表示_,它在任何地方都不可见。

请注意,AM[A]这种情况下会忽略 in。它可能是T并且它也会起作用:

scala> case class MyContainer[A, M[T]](el: M[A])
defined class MyContainer

scala> val mc1 = MyContainer[Int, Option](Some(3))
mc1: MyContainer[Int,Option] = MyContainer(Some(3))

为了防止混淆,我总是使用[_],或者至少不重复使用这些名称。

于 2014-10-05T16:47:13.273 回答