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

Scala case matching using inductive structure failing while mapping a list

在这里我试图实现以下目标:

  1. 使用递归,return一个包含列表 l 的所有元素的新列表,当对它们调用函数 f 时 return 为真。

  2. returned 列表元素必须保持与原始列表相同的顺序。

编辑:

到目前为止,我已经能够消除类型不匹配错误。我的目标是在给定定义的情况下遍历列表并 return 创建一个新列表似乎还很遥远。

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, Cons(j, Nil)) if f(i) == true => filterNumList(Cons(i, Nil),f)
            case Cons(i, rest) if f(i) == true => filterNumList(Cons(i,rest),f)
            case Cons(i, Cons(j, rest)) if f(i) == false => filterNumList(Cons(j, rest),f)
        }
}

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

你要探索的案例比你放下的要简单。

您感兴趣的有:

  1. 列表为空:
    • 此处无事可做,只是 return 空列表
  2. 列表的第一项满足谓词:
    • 构建一个列表
      • 包含第一项
      • 然后将过滤器应用于列表的其余部分
  3. 第一项满足谓词:
    • 只是 return 将过滤器应用于列表的其余部分的结果

在伪代码中这将是:

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