Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala:缺少参数类型_Scala - Fatal编程技术网

Scala:缺少参数类型

Scala:缺少参数类型,scala,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 ((

我在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)
scala>List(1,2,3).toSet.subsets(2).map(u.toList)
res0:Iterator[List[Int]]=非空迭代器
scala>List(1,2,3).toSet.subsets.map(u.toList)
:8:错误:缺少扩展函数的参数类型((x$1)=>x$1.toList)
列表(1,2,3).toSet.subsets.map(u.toList)

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

子集可能是另一个重载的部分应用。

这似乎是编译器的问题

比较:

scala> List(1,2,3).toSet.subsets
res4: Iterator[scala.collection.immutable.Set[Int]] = non-empty iterator

scala> res4.map(_.toList)
res5: Iterator[List[Int]] = non-empty iterator

这很可能是编译器本身的问题,因为它无法进行类型推断。我以前也遇到过类似的问题

如果您快速浏览一下
Set
的定义,它们共享相同的返回类型,因此它们都应该工作,对吗

要解决此问题,这将起到以下作用:

(List(1, 2, 3).toSet.subsets: Iterator[Set[Int]]).map(_.toList)

矛盾的是,第一个版本之所以有效,是因为应用程序
子集(2)
中的
子集(2)
比没有paren时更加模糊

由于方法重载,在应用程序中,编译器暂停求解
toSet
B
结果,并确定
B
Int
。因此它知道
映射的参数类型

在没有参数的版本中,带有参数列表的方法不是候选方法,因为不会触发eta扩展。因此,当它键入
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)
}
原始代码上的
-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]]
让我们看看他们是否会接受库更改:


我猜
.subsets
更加模糊(它可能是接受参数的版本的部分应用程序),因此类型推断工作得不太好。在任何情况下,您都可以按照编译器的指示进行编译,并提供一个显式类型:
List(1,2,3).toSet.subsets.map{x:Set[Int]=>x.toList}
,但根据2.10.4 scaladoc:
def subsets:Iterator[Set[A]
def subsets(len:Int):Iterator[Set[A]]
因此,就类型而言,应该没有任何区别,对吧?在Scala中,当一个方法
def子集(i:Int)(d:Double):迭代器[Set[a]
会导致对重载定义的
引用不明确时,允许这些方法一起使用,这不是不一致吗?如果是
Set(1,2,3).子集
它可以工作。如果你用
…子集match{case x=>x.map(u.toList)}
来分解它,它也会起作用。@21不对称性在于
子集
可以是
子集(Int)
的部分应用,而
子集(2)
不能是
子集
的部分应用。(但这只是猜测)。您错误地引用了没有参数列表的
子集。否则就不会有问题了
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