映射列表时,使用归纳结构的Scala大小写匹配失败

问题描述

我正在尝试实现以下目标:

  1. 使用递归,返回一个新列表,该列表由列表l的所有元素组成,当对它们调用函数f时,它们将返回true。

  2. 返回的列表元素必须保留与原始列表相同的顺序。

编辑:

到目前为止,我已经能够消除类型错误。我迭代给定定义的列表并返回新列表的目标似乎还很遥远。

sealed trait NumList
case object Nil extends NumList
case class Cons(n: Int,l: NumList) extends NumList

def filterNumList(l: NumList,f: Int => Boolean): NumList = {
    l match {
            case Nil => Nil
            case Cons(i,Nil) => Cons(i,Nil)
            case Cons(i,Cons(j,Nil)) if f(i) == false => filterNumList(Cons(j,Nil),f)
            case Cons(i,Nil)) if f(i) == true => filterNumList(Cons(i,rest) if f(i) == true => filterNumList(Cons(i,rest),rest)) if f(i) == false => filterNumList(Cons(j,f)
        }
}

val l1 = Cons(12,Cons(25,Cons(37,Nil)))
def f1(j: Int): Boolean =  j <= 25 && j >= 12
println(filterNumList(l1,f1))

解决方法

您要研究的案例比您要提出的案例要简单。

您感兴趣的是:

  1. 列表为空:
    • 这里什么也没做,只需返回空白列表
  2. 列表的第一项满足谓词:
    • 构造一个列表
      • 包含第一项
      • 随后将过滤器应用于列表的其余部分
  3. 第一项满足谓词:
    • 只返回将过滤器应用于列表其余部分的结果

在伪代码中,这将是:

function filter(list,predicate)
  if empty(list)
    return the empty list
  else
    if predicate(head(list)) is true
      cons(head(list),filter(tail(list),predicate))
    else
      filter(tail(list),predicate)

在Scala中,这应该满足您的要求:

sealed trait NumList
case object Nil extends NumList
case class Cons(n: Int,l: NumList) extends NumList

def filterNumList(l: NumList,f: Int => Boolean): NumList = {
  l match {
    case Nil                         => Nil
    case Cons(head,tail) if f(head) => Cons(head,filterNumList(tail,f))
    case Cons(head,tail)            => filterNumList(tail,f)
  }
}

val l1 = Cons(12,Cons(25,Cons(37,Nil)))
def f1(j: Int): Boolean = j <= 25 && j >= 12
println(filterNumList(l1,f1))

您可以使用此代码here on Scastie