问题描述
我正在尝试实现以下目标:
编辑:
到目前为止,我已经能够消除类型错误。我迭代给定定义的列表并返回新列表的目标似乎还很遥远。
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))
解决方法
您要研究的案例比您要提出的案例要简单。
您感兴趣的是:
- 列表为空:
- 这里什么也没做,只需返回空白列表
- 列表的第一项满足谓词:
- 构造一个列表
- 包含第一项
- 随后将过滤器应用于列表的其余部分
- 构造一个列表
- 第一项不满足谓词:
- 只返回将过滤器应用于列表其余部分的结果
在伪代码中,这将是:
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。