我正在尝试编写一个简单的查询monad,并且遇到问题,我的通用类型注释正确。Scala推断的类型参数 - 类型范围推断为'Nothing'
我第一次尝试去如下(大大简化了简洁)
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”的类型。
error: inferred type arguments [People.type,Nothing] do not conform to method apply's type parameter bounds [U <: Schema[T],T]
虽然尝试我发现,使用视图的边界,而不是按预期工作
case class Query[U <% Schema[T], T](schema: U) {
(注意使用的角度约束“<%”,而不是约束型“<”)
然而,在我对类型系统有限的理解中,因为我期待Schema [T]的实际子类(而不仅仅是可转换性),所以我会假定类型绑定“<:”是在这里使用的正确界限?
如果是这样的话,我错过了什么 - 我怎么给编译器足够的提示,以便在使用类型边界而不是视图边界时正确推断T?
谢谢。我曾经看到过这种语法,并在想这是什么意思。 – 2013-05-01 06:36:24
我不认为这个答案是正确的。请在我的答案底部查看我的回复(此评论不会为讨论提供足够的空间)。 – 2013-05-01 09:01:01
@Régis你是对的。我误解了规范中的范围规则。这确实是一个推理问题,正如你在答案中所描述的那样。也就是说,使用隐式证据参数是对关系进行编码并支持所需推理的最简单方法。 – 2013-05-01 19:51:11