我试图声明一个带有两个类型参数的case类:具体类型A
和类型构造函数D
,被约束为已知类型的子类。我的案例类将包含List[D[A]]
。
我遇到的问题是,每当我在该列表上进行映射时,我似乎都会丢失D
所包含类型的信息。
以下是我所拥有的:
// Represents a named collection of documents of type A
trait Documents[A] {
def name: String
def take(target: Int): Documents[A]
// [...]
}
// Represents a collection of named collections of documents.
// A is the type of a document, D that of a named collection of documents
case class Data[A, D[_] <: Documents[_]](docs: List[D[A]]) {
// Makes sure no D contains more than target documents
def cap(target: Int): Data[A, Documents] = {
Data(docs.map(_.take(target)))
}
// [...]
}
无法使用以下令人困惑的错误消息进行编译:
type mismatch;
[error] found : List[Documents[_]]
[error] required: List[Documents[A]]
[error] Data(docs.map(_.take(target)))
[error] ^
我不明白将函数D[A] => Documents[A]
应用于D[A]
如何产生Documents[_]
......
答案 0 :(得分:1)
问题是Documents[_]
正在使用存在类型,这意味着您告诉编译器您不关心D
中包含的类型。因此,即使您指定docs
是List[D[A]]
,编译器也只会将其视为List[D[_]]
。你真正想要的是使用自由类型参数,而不是类型约束中的通配符。即D[B] <: Documents[B]
import scala.language.higherKinds
trait Documents[A] {
def name: String
def take(target: Int): Documents[A]
}
case class Data[A, D[B] <: Documents[B]](docs: List[D[A]]) {
def cap(target: Int): Data[A, Documents] = {
Data(docs.map(_.take(target)))
}
}