简体   繁体   English

在较高级别的类型上输入推断

[英]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. typeTestA[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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM