无法证明“ a Tuple2” <:<(T,U)

Tro*_*els 6 scala

我正在尝试从输入映射构建映射,但是编译器无法证明2元素元组是2元素元组。

class Element[T] extends AnyRef { }

class Sample
{
    def makeList(x:Int): Element[_] = {
        x match {
            case 1 => new Element[Boolean]
            case 2 => new Element[(Boolean, Boolean)]
        }
    }

    val input = Map(1 -> "one",2 -> "two")

    val output = input.map(e => e._1 -> makeList(e._1)).toMap
}
Run Code Online (Sandbox Code Playgroud)

sbt编译

sbt:root> ~compile
[info] Compiling 1 Scala source to /Users/tda0106/test/scala/target/scala-2.12/classes ...
[error] /Users/tda0106/test/scala/src/main/scala/Test.scala:14:57: Cannot prove that (Int, Element[_$1]) forSome { type _$1 } <:< (T, U).
[error]     val output = input.map(e => e._1 -> makeList(e._1)).toMap
[error]                                                         ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 1 s, completed Jun 27, 2019, 2:38:14 PM
Run Code Online (Sandbox Code Playgroud)

问题似乎与有关forSome { type _$1 },否则应该匹配。当我第一次尝试重现它时,我使用List代替Element它并对其进行了编译。似乎不同之处在于,此处List声明为List[+T],而+此处很重要。

Element 是来自第三方图书馆,因此很难进行更改。

我在这里遇到什么问题,有没有简单的方法可以解决?

Scala版本:2.12.8

Sil*_*olo 6

当您在使用存在性做事时(这就是事实),Scala有时会在类型推断方面变幻无常Element[_]。快速的显式类型签名将解决此问题。

val output = input.map(e => e._1 -> makeList(e._1)).toMap[Int, Element[_]]
Run Code Online (Sandbox Code Playgroud)

您要做的就是告诉编译器您想要键和值的类型。无法推理的原因漫长而复杂,但是作为一般规则,一旦开始在类型中添加下划线,您将失去一些推理功能。