scala - 无法理解 flatMap 如何消除 Nil 元素
问题描述
我正在阅读 Scala 中的函数式编程一书,在数据结构一章的末尾,您被要求filter
根据flatMap
. 以下是必要的功能和实现:
sealed trait List[+A]
case object Nil extends List[Nothing]
case class Cons[+A](head: A, tail: List[A]) extends List[A]
object List {
def apply[A](as: A*): List[A] = {
if (as.isEmpty) Nil
else Cons(as.head, apply(as.tail: _*))
}
def append[A](l1: List[A], l2: List[A]): List[A] = {
foldRight(l1, l2)((elem, acc) => Cons(elem, acc))
}
def concat[A](ls: List[List[A]]): List[A] = {
foldLeft(ls, Nil: List[A])(append)
}
def map[A, B](l: List[A])(f: A => B): List[B] = {
foldRight(l, Nil: List[B])((elem, acc) => Cons(f(elem), acc))
}
def filter[A](l: List[A])(f: A => Boolean): List[A] = {
List.flatMap(l)(a => if (f(a)) List(a) else Nil)
}
def flatMap[A, B](l: List[A])(f: A => List[B]): List[B] = {
concat(map(l)(f))
}
def foldRight[A, B](l: List[A], z: B)(f: (A, B) => B): B = {
l match {
case Nil => z
case Cons(h, t) => f(h, foldRight(t, z)(f))
}
}
def foldLeft[A, B](l: List[A], z: B)(f: (B, A) => B): B = {
l match {
case Nil => z
case Cons(h, t) => foldLeft(t, f(z, h))(f)
}
}
}
实际的函数调用在这里:
val x = List(1, 2, 3, 4, 5)
List.filter(x)(_ < 3)
据我所知,在映射步骤之后,您将拥有一个如下所示的列表:
Cons(Cons(1, Nil), Cons(2, Nil), Cons(Nil, Nil)...
我无法查看Nil
从最终结果中过滤掉的元素的位置。
解决方案
它们没有被“过滤掉”。在您应用到列表列表后,它们就会消失concat
,因为与空列表的连接没有任何作用。
推荐阅读
- perl - 在文件中剪切并粘贴特定字符串
- azure - 将 Azure 数据工厂管道有条件地部署到另一个资源组
- javascript - ReactJS - 从 innerHtml 函数返回一个组件
- android - 在 Android Q API 29 中使用 getNeighboringCellInfo() 会给出错误“无法解析方法”而不是弃用警告
- javascript - 在 iframe 中单击按钮时从输入字段加载网页
- javascript - 无法检查文件是否存在于纯 JavaScript 中
- javascript - 尝试使用带有 AngularJS 的 Web 部件页在我的 SharePoint Online 自定义列表中显示数据
- ios - 如何使用 arkit 人脸跟踪获取 3d 位置数据?
- javascript - 如何从ajax调用更改php变量?
- javascript - jQuery在拖动时更新DOM