我正在尝试编写一个简单的查询monad,但是在正确注释我的泛型类型时遇到了问题。
我的第一次尝试如下(为了简洁起见大大简化)
case class Person( val name: String )
abstract class Schema[T]
object People extends Schema[Person]
case class Query[U <: Schema[T], T]( schema: U ) { <---- Type signature
def results: Seq[T] = ...
def where( f: U => Operation ) = ...
}
class TypeText extends Application {
val query = Query( People ) <---- Type inference fails
}
编译器不喜欢这样做,因为它无法推断出“T”的类型。
错误:推断的类型参数[People.type,Nothing]不符合方法应用的类型参数边界[U <: Schema[T],T]
在实验中,我发现使用视图界定(view bounds)可以正常工作。
case class Query[U <% Schema[T], T]( schema: U ) {
(请注意使用了视图界定“<%”而不是类型界定“<:”)
然而,在我有限的类型系统理解中,因为我期望一个实际的子类(而不仅仅是可转换性)Schema[T],我会认为类型界定“<:”是正确的边界应该在这里使用?
如果是这种情况,我错过了什么 - 当使用类型界定而不是视图界定时,我如何给编译器足够的提示来正确地推断T?