【问题标题】:Pattern Matching on lists behaving weird?列表上的模式匹配表现得很奇怪?
【发布时间】:2016-03-01 02:05:02
【问题描述】:

在练习 scala 时,我正在尝试使用模式匹配对整数列表进行插入排序。以前,打印列表的以下代码工作得非常好:

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)
  }
}

但是,以下用于对列表进行排序的代码无法编译:

  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

  }

我在这里错过了什么非常琐碎的事情吗??

编辑: 修改代码如下:

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]

将 Intellij Idea 与 Scala 插件一起使用 - 2.11.7。

【问题讨论】:

  • 您可能想要添加编译器错误。我不明白。 insert 采用什么参数?因为它看起来只需要一个 List 参数,但您使用 2 个参数调用它。
  • 您可能需要指定返回列表的类型:List[Int],而且您的插入方法只需要一个参数,而不是两个。
  • 正如@hasumedic 指出的那样,您还需要为返回的List...指定一个类型参数... 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中的代码

标签: scala pattern-matching


【解决方案1】:

查看your screenshot,您正在同一个包Week04 中定义自己的List 类。它在左侧的项目浏览器中可见。所以在你的代码中

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 也非常感谢您的回答:) 真的很有帮助!
猜你喜欢
  • 1970-01-01
  • 2013-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-14
  • 2014-12-12
  • 2012-11-11
  • 1970-01-01
相关资源
最近更新 更多