Dyl*_*lan 6 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) // error: inferred [Nothing, Minimal[Int]] does not fit the bounds of apply
Sugar[Int, Minimal[Int]](a) // works as expected
}
Run Code Online (Sandbox Code Playgroud)
问题是编译器设法找出Minimal
(Int
)的内部参数,但然后设置T
to 的另一个匹配Nothing
,显然不匹配apply
.这些肯定是一样的T
,因为删除第一个参数会使第二个参数抱怨T未定义.
是否有一些含糊不清意味着编译器无法推断出第一个参数,或者这是一个错误?我可以优雅地解决这个问题吗?
更多信息:此代码是尝试语法糖的简单示例.原始代码试图使|(a)|
模数为均值a
,其中a是向量.显然|(a)|
比写作更好|[Float,Vector3[Float]](a)|
,但不幸的是我不能unary_|
用来使这更容易.
实际错误:
推断类型参数[Nothing,Minimal [Int]]不符合方法apply的类型参数bounds [T,X <:Sugar.S [T]]
这不是Scala编译器错误,但它肯定是Scala类型推断的限制.编译器想要确定结合的上X
,S[T]
,求解之前X
,但结合提到迄今无约束类型的变量T
,因此,它固定在Nothing
并进行从那里.T
一旦X
完全解决,它就不再重新审视......目前,在这种情况下,类型推断总是从左到右进行.
如果您的示例准确地表示您的实际情况,那么有一个简单的修复,
def apply[T](x : S[T]) = x.doSomething
Run Code Online (Sandbox Code Playgroud)
这里T
将推断Minimal
为S[T]
直接符合而不是通过中间有界类型变量.
更新
约书亚的解决方案也避免了推断类型的问题T
,但是以完全不同的方式.
def apply[T, X <% S[T]](x : X) = x.doSomething
Run Code Online (Sandbox Code Playgroud)
desugars,
def apply[T, X](x : X)(implicit conv : X => S[T]) = x.doSomething
Run Code Online (Sandbox Code Playgroud)
的类型变量T
和X
现在可以解决的,用于独立地(因为T
在不再提及X
的结合).这意味着立即X
推断Minimal
,并T
作为隐式搜索类型值的一部分来解决,X => S[T]
以满足隐式参数conv
.conforms
在scala.Predef
制造这种形式的价值,并在上下文中将保证给定一个类型的参数Minimal
,T
将推断为Int.您可以将其视为Scala中工作的函数依赖项的实例.
归档时间: |
|
查看次数: |
438 次 |
最近记录: |