试图弄清楚为什么代码对使用arity-2而不是使用currying的方法进行嵌套类型推断的编译。
object Test
{
trait Version
object VersionOne extends Version
trait Request[A <: Version]
trait RequestOne extends Request[VersionOne.type]
case class HelloWorld() extends RequestOne
def test1[A <: Version, T <: Request[A]](t : T, a : A): T = t
def test2[A <: Version, T <: Request[A]](t : T)(a : A): T = t
}
// This works
Test.test1(Test.HelloWorld(), Test.VersionOne)
// This doesn't
Test.test2(Test.HelloWorld())(Test.VersionOne)
test2无法编译,并出现以下错误:
错误:(22,73)推断的类型参数[Nothing,A $ A96.this.Test.HelloWorld]不符合方法test2的类型参数范围[A <:A $ A96.this.Test.Version,T <:A $ A96.this.Test.Request [A] def get $$ instance $$ res1 = / * ### worksheet ###生成$$ end $$ * / Test.test2(Test.HelloWorld())(Test.VersionOne)
期待对此有一些见识。
答案 0 :(得分:1)
Nothing
出现编译错误通常表示未推断某些类型参数。
尝试明确指定它们
Test.test2[Test.VersionOne.type, Test.RequestOne](Test.HelloWorld())(Test.VersionOne)
test1
和test2
之间的区别不仅在于汇率。例如,通常test2(t: ...)(a: ...)
的{{1}}类型可以取决于a
的值。因此,对于t
,类型推断要比test2
复杂。
Scala type inference and multiple arguments list
Type inference with type aliases and multiple parameter list function
Multiple parameter closure argument type not inferred
What's the difference between multiple parameters lists and multiple parameters per list in Scala?
答案 1 :(得分:1)
@DmytroMitin已经解释了失败的原因。
但是,您可以使用Partially-Applied Type技巧和Generalized Type Constraints来解决问题。
def test2[T](t: T): Test2PartiallyApplied[T] = new Test2PartiallyApplied(t)
final class Test2PartiallyApplied[T](private val t: T) extends AnyVal {
def apply[A <: Version](a: A)(implicit ev: T <:< Request[A]): T = t
}
您可以这样使用。
Test.test2(Test.HelloWorld())(Test.VersionOne)
// res: HelloWorld = HelloWorld()