Scala:缺少参数类型

the*_*1st 13 scala

我在Scala-REPL中输入以下内容:

scala> List(1, 2, 3).toSet.subsets(2).map(_.toList)
res0: Iterator[List[Int]] = non-empty iterator

scala> List(1, 2, 3).toSet.subsets.map(_.toList)
<console>:8: error: missing parameter type for expanded function ((x$1) => x$1.toList)
              List(1, 2, 3).toSet.subsets.map(_.toList)
Run Code Online (Sandbox Code Playgroud)

为什么我在第二行遇到错误?这是编译器中的错误还是我遗漏了什么?

som*_*ytt 5

矛盾的是,第一个版本有效,因为subsets在应用程序subsets(2)中,可以说比没有括号更模糊。

由于方法重载,在应用程序中,编译器暂停求解 的B结果toSet,并决定BInt。因此它知道map.

在没有括号的版本中,带有参数列表的方法不是候选方法,因为没有触发 eta-expansion。所以当它键入map应用程序时,它没有得出任何关于 的结论B,它是映射函数的输入类型。

简单的解决方法是告诉它推断B

trait Test {
  def f1 = List(1, 2, 3).to[Set].subsets.map(_.toList) // instead of .toSet
  def f2 = List(1, 2, 3).toSet.subsets(2).map(_.toList)
}
Run Code Online (Sandbox Code Playgroud)

-Ytyper-debug原始代码上的输出显示了重载解析是如何进行类型推断的:

|    |    |    |    |    |    \-> => Iterator[scala.collection.immutable.Set[B]] <and> (len: Int)Iterator[scala.collection.immutable.Set[B]]
|    |    |    |    |    solving for (B: ?B)
|    |    |    |    |    |-- 2 : pt=Int BYVALmode-EXPRmode-POLYmode (silent: method f2 in Test) 
|    |    |    |    |    |    \-> Int(2)
|    |    |    |    |    solving for (B: ?B)
|    |    |    |    |    \-> Iterator[scala.collection.immutable.Set[Int]]
Run Code Online (Sandbox Code Playgroud)

另一种解决方法是通过扩展方法:

scala> implicit class ss[A](val s: Set[A]) { def ss(n: Int) = s subsets n ; def ss = s.subsets }
defined class ss

scala> List(1, 2, 3).toSet.ss.map(_.toList)
res1: Iterator[List[Int]] = non-empty iterator
Run Code Online (Sandbox Code Playgroud)

让我们看看他们是否会改变图书馆:

https://github.com/scala/scala/pull/4270