为什么在这里不类型推断的工作?(Why doesn't type inference wor

2019-07-29 04:28发布

这个问题的模块,我在写作出现,但我已经表现出相同的行为一个最小的情况下。

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
}

问题是,编译器设法找出内部参数MinimalInt ),但随后设置的其他发生TNothing ,这显然不符合apply 。 这些是绝对相同的T ,去掉了第一个参数使第二抱怨T没有限定。

有一些不确定性,这意味着编译器不能推断第一个参数,或者这是一个错误? 我可以解决这个优雅?

进一步的信息:该代码在语法糖的尝试的一个简单的例子。 原来的代码试图让|(a)| 平均模量a ,其中a是一个矢量。 显然|(a)| 比写更好|[Float,Vector3[Float]](a)| ,但遗憾的是我不能使用unary_| 使它更容易些。

实际的错误:

推断出的类型的参数[没什么,最小[INT]]不符合方法应用的类型参数界限[T,X <:Sugar.S [T]]

Answer 1:

这不是一个Scala编译器错误,但它肯定是Scala的类型推断的限制。 编译器想要确定结合在XS[T]求解之前X ,但结合提到迄今无约束型可变T因此它固定在Nothing并且前进从那里。 它不会再讲T一次X已经完全解决。目前类型推断总是在这种情况下从左到右进行。

如果你的榜样准确地代表你的真实情况,然后有一个简单的解决,

def apply[T](x : S[T]) = x.doSomething

这里T使得将被推断Minimal符合S[T]而不是直接通过中间有界类型的变量。

更新

约书亚的解决方案也避免了类型推断的问题T ,但在一个完全不同的方式。

def apply[T, X <% S[T]](x : X) = x.doSomething

desugars到,

def apply[T, X](x : X)(implicit conv : X => S[T]) = x.doSomething

的类型变量TX现在可以解决的,用于独立地(因为T在不再提及X的结合)。 这意味着, X被推断为Minimal立即,和T式求得作为用于类型的值的隐式搜索的一部分X => S[T]满足隐含参数convconformsscala.Predef制造这种形式的值,并且在上下文将保证给定的类型的参数MinimalT将被推断为INT。 你可以认为这是一个实例函数依赖在斯卡拉工作。



Answer 2:

有一些古怪与结构类型界限,尝试使用结合在S [T]代替的图。

def apply[T, X <% S[T]] (x: X) = x.doSomething工作正常。



文章来源: Why doesn't type inference work here?