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 }
问题是编译器设法找出Minimal(Int)的内部参数,但是然后将T的另一个出现设置为nothing,这显然与apply不匹配.这些肯定是相同的T,因为删除第一个参数使第二个抱怨T未定义.
是否有一些含糊不清意味着编译器无法推断出第一个参数,或者这是一个错误?我可以优雅地解决这个问题吗?
更多信息:此代码是尝试语法糖的简单示例.原始代码尝试制作|(a)|表示a的模数,其中a是矢量.显然|(a)|比写[| Float,Vector3 [Float]](a)|更好,但不幸的是我不能使用unary_ |使这更容易.
实际错误:
inferred type arguments [nothing,Minimal[Int]] do not conform to method apply’s type parameter bounds [T,X <: Sugar.S[T]]
解决方法
如果您的示例准确地表示您的实际情况,那么有一个简单的修复,
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
现在可以独立地求解类型变量T和X(因为在X的界限中不再提及T).这意味着X立即被推断为Minimal,并且T被解析为隐式搜索类型X =>的值的一部分. S [T]满足隐式参数conv. scala中的conform.Predef制造这种形式的值,并且在上下文中将保证给定Minimal类型的参数,T将被推断为Int.您可以在Scala中将其视为functional dependencies的实例.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。