Scala 为什么可以';我不会写‘列表’,但我会写';I';

Scala 为什么可以';我不会写‘列表’,但我会写';I';,scala,Scala,在下面的代码中,我可以将id定义为List[I] abstract trait Repository[I,M] { def getOneById(id: List[I]): Option[M] } 但是为什么我不能在下面的代码中将id定义为List[I] abstract trait Repository[List[I],M] { def getOneById(id: List[I]): Option[M] //I get compiler error - cannot r

在下面的代码中,我可以将
id
定义为
List[I]

abstract trait Repository[I,M] {

    def getOneById(id: List[I]): Option[M]
}
但是为什么我不能在下面的代码中将
id
定义为
List[I]

abstract trait Repository[List[I],M] {

    def getOneById(id: List[I]): Option[M] //I get compiler error - cannot resolve I. Why?
}

应该有用。基本上,在trait定义中,您只列出typearguments,而在id的右侧,您需要指定一个类型
List
是一个类型构造函数,在您的案例中接受一个参数
I

编辑:请参见中的注释链

abstract trait Repository[List[I],M] {
    def getOneById(id: List[I]): Option[M]
}
List
是与类型
scala.Predef.List
无关的类型参数的名称。而
[List[I],M]
中的
I
仅意味着该类型参数本身是一个接受单个类型参数的泛型类型。此名称
I
仅在
列表[I]
中可见

因此,这可以同样改写为

abstract trait Repository[F[_],M] {
    def getOneById(id: F[I]): Option[M]
}

这应该可以清楚地说明为什么这个不能编译。

对不起,我知道第一个可以。我试图理解为什么第二个没有,因为
List
也是一种类型,不是吗?
List
是一种类型构造函数
List[Int]
是一种类型。但这很挑剔。它不起作用的原因是你可以想到
。。。trait Repository[I,M]
类似于
def Repository
,但用于类型
[I,M]
只是说
Repository
接受两个类型参数
I
M
,因此表达式
List[I]
在该位置没有多大意义。在作为
id
函数参数的位置上,它是有意义的,因为
id
必须是作为
I
传递到
Repository
的任何内容的
列表。“表达式列表[I]在该位置上没有多大意义”它对编译器来说是完全有意义的,问题是它的意义不是我们想要的。好的,我必须修改。在吉特,我不得不问比我聪明的人。基本上,您绑定了一个名为list的类型参数*->*和它的类型参数I(与scala list无关)。然而,我是无效的,但可以这样使用
trait Repository[F[I]谢谢Alexey.Undersood。
abstract trait Repository[F[_],M] {
    def getOneById(id: F[I]): Option[M]
}