[英]Type inference on higher-kinded types
Trying to understand what "type" actually means in scala. 试图理解scala中“类型”的实际含义。 Here is an example:
这是一个例子:
trait A[T]
trait B[T]
val typeTest = new A[Int] with B[String]
def test [F[_],T] (t:F[T],tt:T):T= tt
test(typeTest,5) // line #1: compiles
test(typeTest,"5") // line #2: failed
typeTest
is A[Int]
an B[String]
at the same time. typeTest
是A[Int]
和B[String]
。 Why line #1 compiles and #2 failed? 为什么第1行编译而#2失败? Why
T
is inferred only for Int
? 为什么
T
仅为Int
推断?
The easiest way to make this code compile is to provide a hint for compiler 编译此代码的最简单方法是为编译器提供提示
test[B, String](typeTest,"5")
or 要么
test(typeTest: B[String],"5")
It's funny that with the nightly build of Dotty vice versa 有趣的是,Dotty的夜间构建反之亦然
val typeTest = new A[Int] with B[String] {}
test(typeTest,"5")
compiles but 编译但是
test(typeTest,5)
doesn't 不
[error] found: Int(5)
[error] required: String
[error]
[error] test(typeTest,5)
[error] ^
[error] one error found
and one should provide a hint 一个人应该提供一个提示
test[A, Int](typeTest,5)
For comparison Scalac compile error was 为了比较Scalac编译错误是
Error: type mismatch;
found : A[Int] with B[String]
required: A[Any]
Note: Int <: Any (and A[Int] with B[String] <: A[Int]), but trait A is invariant in type T.
You may wish to define T as +T instead. (SLS 4.5)
test(typeTest,"5")
The fact that currently Scalac and Dotty behaves (infer types) here differently means that (according to Scala specification) there is no deep difference betweeen test(typeTest,5)
and test(typeTest,"5")
cases. 目前Scalac和Dotty在这里表现不同(推断类型)这一事实意味着(根据Scala规范),
test(typeTest,5)
和test(typeTest,"5")
情况之间没有深刻的差异。 It's just imperfectness of type inference algorithms used by different compilers. 这只是不同编译器使用的类型推断算法的不完美之处。
By the way, as follows from Scalac compile error message, one more option to help compilers to infer correct types is to make a trait covariant: 顺便说一句,如下Scalac编译错误消息,帮助编译器推断正确类型的另一个选项是使特征协变:
trait A[+T]
trait B[T]
val typeTest = new A[Int] with B[String]
test(typeTest,5)
test(typeTest,"5")
for Scalac and 对于Scalac和
trait A[+T]
trait B[+T]
val typeTest = new A[Int] with B[String] {}
test(typeTest,5)
test(typeTest,"5")
for Dotty. 对于Dotty。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.