Scala 为什么';t型推理在这里工作?
这个问题出现在我正在编写的一个模块中,但我做了一个展示相同行为的最小案例Scala 为什么';t型推理在这里工作?,scala,structural-typing,type-bounds,Scala,Structural Typing,Type Bounds,这个问题出现在我正在编写的一个模块中,但我做了一个展示相同行为的最小案例 class Minimal[T](x : T) { def doSomething = x } object Sugar { type S[T] = { def doSomething : T } def apply[T, X <: S[T]] (x: X) = x.doSomething } object Error { val a = new Minimal(4) Sugar(a) //
class Minimal[T](x : T) {
def doSomething = x
}
object Sugar {
type S[T] = { def doSomething : T }
def apply[T, X <: S[T]] (x: X) = x.doSomething
}
object Error {
val a = new Minimal(4)
Sugar(a) // error: inferred [Nothing, Minimal[Int]] does not fit the bounds of apply
Sugar[Int, Minimal[Int]](a) // works as expected
}
类最小[T](x:T){
def剂量计=x
}
目标糖{
类型S[T]={def doSomething:T}
def apply[T,X结构类型的边界有些奇怪,请尝试使用s[T]上的视图边界
def apply[T,X这不是Scala编译器的错误,但它肯定是Scala类型推断的一个限制。编译器想要确定X
,s[T]上的界限
,在求解X
之前,但边界提到了迄今为止未受约束的类型变量T
,因此它将其固定在Nothing
并从那里继续。一旦X
得到完全解决,它就不会重新访问T
。当前类型推断总是以这种方式从左到右进行当然
如果你的例子准确地反映了你的真实情况,那么有一个简单的解决办法
def apply[T](x : S[T]) = x.doSomething
这里将推断出T
,使得最小值
直接符合S[T]
,而不是通过中间有界类型变量
更新
Joshua的解决方案也避免了推断类型T
的问题,但方式完全不同
def apply[T, X <% S[T]](x : X) = x.doSomething
类型变量T
和X
现在可以独立求解(因为T
在X
的范围中不再提及)。这意味着X
立即被推断为最小值s[T],并且T
作为隐式搜索X=>s[T]类型值的一部分求解
为了满足scala中的隐式参数conv
符合的要求。Predef
制造这种形式的值,并且在上下文中将保证给定类型为Minimal
的参数,T
将被推断为Int。您可以将其视为scala中工作的一个实例。很好,这很有效,但是不确定这两种方法之间应该没有区别吗?在这种情况下,查看只是对一个超类进行强制转换,不是吗?这是否意味着此修复只是编译器中一个bug的解决方法?啊,现在我明白了,S
不是一个超类-它只是一个视图(在某种意义上)。因此,视图绑定更合适,尽管在大多数情况下不需要。是的,这个解决方案在我的情况下工作得很好。它也比Joshua的解决方案(对不起Joshua!)更干净。那么,你能解释Joshua的解决方案工作的原因吗?更新答案,解释Joshua的解决方案也工作的原因。
def apply[T, X](x : X)(implicit conv : X => S[T]) = x.doSomething