使用类型参数时,Scala“不采用任何类型参数,预期:一个”

时间:2016-03-12 00:37:30

标签: scala generics types

我想编写一个方法,对值的map的子类型进行操作,以便遍历。我的第一次尝试是将其定义为:

def m[A, B, T[B] <: Traversable[B], M[A, T[B]] <: collection.Map[A, T[B]]](m: M[A, T[B]]): M[A, T[B]]

但是,这个定义给出了以下类型错误:

T[B] takes no type parameters, expected: one
  def m[A, B, T[B] <: Traversable[B], M[A, T[B]] <: collection.Map[A, T[B]]](m: M[A, T[B]]): M[A, T[B]] = {
                                                                                              ^

T[B] takes no type parameters, expected: one
  def m[A, B, T[B] <: Traversable[B], M[A, T[B]] <: collection.Map[A, T[B]]](m: M[A, T[B]]): M[A, T[B]] = {
                                                                                 ^

我认为T[B] <: Traversable[B]M[A, T[B]] <: M[A, T[B]]的定义没有任何区别,只有一个类型参数级别。

当我使用另一个类型参数M进行参数化时,我得到了同样的错误:

def m[A, B, C, T[B] <: Traversable[B], M[C, T[C]] <: collection.Map[C, T[C]]](m: M[C, T[C]]): M[C, T[C]]

如果我将签名更改为

def m[A, B, T[B] <: Traversable[B], M <: collection.Map[A, T[B]]](m: M): M

并从M中删除类型参数,编译错误消失。任何人都可以向我解释第一个版本的问题是什么?

最后一个版本编译,但在调用站点给出类型错误,所以我猜应该以某种方式提供类型参数。例如

val map = mutable.Map.empty[Int, Set[Int]]
m(map)

给出

inferred type arguments [Nothing,Nothing,Nothing,scala.collection.mutable.Map[Int,Set[Int]]] do not conform to method m's type parameter bounds [A,B,T[B] <: Traversable[B],M <: scala.collection.Map[A,T[B]]]
  m(map)
   ^

1 个答案:

答案 0 :(得分:3)

类似T[B] <: Traverable[B]的绑定类型不应引用其他类型参数。相反,B意味着“自由”参数。您应该将其替换为其他符号,例如T[X] <: Traverable[X]。您也不需要完全要求M[A, T[B]] <: Map[A, T[B]],因为T[B]已经绑定在其他位置。您可以将其替换为M[Y, Z] <: Map[Y, Z]

def m[A, B, T[X] <: Traversable[X], M[Y, Z] <: collection.Map[Y, Z]](m: M[A, T[B]]): M[A, T[B]] = m

scala> m(collection.mutable.Map.empty[Int, Set[Int]])
res6: scala.collection.mutable.Map[Int,Set[Int]] = Map() // correctly inferred

scala> m(collection.mutable.Map.empty[Int, Int]) // fails to conform
<console>:12: error: no type parameters for method m: (m: M[A,T[B]])M[A,T[B]] exist so that it can be applied to arguments (scala.collection.mutable.Map[Int,Int])