Pattern Matching on lists behaving weird?
在练习 scala 时,我正在尝试使用模式匹配对整数列表进行插入排序。以前,用于打印列表的以下代码工作得非常好:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| object PrintList {
def iPrint (xs : List [Int ]):Unit = xs match {
case x :: ys => {
print (x+ " ->")
iPrint (ys )
}
case _ => println ("Nil")
}
def main (args : Array [String ]) {
//val l = Nil.::(1).::(2).::(3).::(4)
val l = 4 :: 3 :: 2 :: 1 :: Nil
iPrint (l )
}
} |
但是,以下用于对列表进行排序的代码无法编译:
1 2 3 4 5 6 7 8 9 10 11
| def insert (x : Int, l1 : List [Int ]):List = {
//stubbed
List ()
}
def iSort (l : List [Int ]):List = l match {
case x :: ys => insert (x , iSort (ys ))
case Nil => Nil
} |
我在这里错过了什么非常琐碎的事情吗??
编辑:
修改代码如下:
1 2 3 4 5 6 7 8 9 10
| def insert (x : Int , l1 : List [Int ]):List [Int ] = {
//stubbed
List (0)
}
def iSort (l : List [Int ]):List [Int ] = l match {
case (x :Int ) :: (ys :List [Int ]) => insert (x , iSort (ys ))
case _ => List (0)
} |
在第一个 case 语句中仍然出现错误 - Pattern type is incompatible with expected type. Found: ::[B], expected: List[Int]
在 Scala 插件中使用 Intellij Idea - 2.11.7.
- 您可能想要添加编译器错误。我不明白。 insert 采用什么参数?因为它看起来只需要一个 List 参数,但您使用 2 个参数调用它。
-
您可能需要指定返回列表的类型:List[Int],而且您的 insert 方法只需要一个参数,而不是两个。
-
正如@hasumedic 指出的那样,您还需要为返回的 List... 指定类型参数 ... something List[Int] 以便您的函数变为 def iSort(l : List[Int]): List[Int]...
-
我在最初的问题中犯了一个错误,插入函数有两个参数:一个整数和一个列表。相应地进行了更改。但是,我仍然遇到同样的错误。尝试了所有提到类型参数的排列,仍然无法编译。以下是错误:Pattern type is incompatible with expected type. found::[B], required List[Int]。 - 即使在将类型参数添加到 List 声明并将 case 语句修改为 case (x:Int) :: (ys:List[Int]) => insert(iSort(ys)) 之后。我正在使用带有 scala 插件的 intellij。
-
看起来像 intellij 中的错误。尝试执行scala repl中的代码
-
我刚刚在 IntelliJ 15.0.2 中编译了它,没有任何错误。我的 Scala 版本是 2.11.7
-
代码在命令行上使用 scalac 编译得很好 :) 但我使用的是完全相同的 IntelliJ 和 Scala 版本——分别是 15.0.2 和 2.11.7。我的 IntelliJ 可能有什么问题?
看看你的截图,你正在同一个包Week04中定义你自己的List类。它在左侧的项目浏览器中可见。所以在你的代码
1
| def iSort (l : List [Int ]) = ??? |
你有一个 Week04.List[Int] 类型的参数。您尝试使用 :: list-cons 类对其进行解构。我想你还没有定义你的 :: 版本,至少我不记得这是在 Coursera 类中定义的。所以这里有一个 scala.::,它是 scala.List 的子类型。因此,您正在尝试针对某些完全不同的类型进行模式匹配。如果您将每次出现的 List 替换为 scala.List 您将使用 Scala 的标准列表类,它应该可以工作。如果您希望它与您自己的列表实现一起使用,您需要定义自己的提取器。
- 我很尴尬地说这解决了这个问题。我在另一个文件(List.scala)中定义了我自己的 List[Int] 版本。非常感谢!!但是,我对 scala 不从任何包(如 java.util)导入 List 的事实感到困惑。当有多个可用时,它如何决定使用哪个版本的类?
-
出于好奇,还有一个问题……您是 Martin Odersky 本人吗? :P
-
@AnkitKhettry 哈哈,不,只是碰巧有相同的国籍:) 关于这个问题 - 不用尴尬。名字的阴影是 Scala 中常见的错误来源,编译器实际上可以更好地暗示这一点。
-
是的,相同的国籍,相同的首字母和相同的实力领域。并发的太多了。你可以选择保持你的"神秘气氛"。我会吹嘘自己曾与 MARTIN ODERSKY 对我的朋友们进行过交谈 xD 也非常感谢您的回答:) 真的很有帮助!