SICP 中 `flatmap` 的意义是什么?

What is the significance of `flatmap` in SICP?

(define (accumulate op initial sequence) 
  (if (null? sequence) 
   initial 
   (op (car sequence) 
     (accumulate op initial (cdr sequence))))) 
      
(define (flatmap proc seq) 
  (accumulate append nil (map proc seq)))

以上是 Scheme 中 SICP 的代码片段。为什么需要 flatmap 程序? flatmapmap 有什么区别?

(map proc seq) 将对序列 seq 应用 proc,为每个元素返回一个值。每个这样的值都可能是另一个序列。

(accumulate append nil seq) 将使用 appendseq 中元素的所有副本连接到一个新列表中。

因此,flatmap 将对 seq 的所有元素应用 proc,并生成包含所有结果的新 flattened 列表。从概念上讲,这也是 mapflatmap 在其他语言(Java、Scala 等)中的区别,因为 map 为每个元素生成一个值,而 flatmap 可能会产生多个或 none (感谢 Chris)。

例如,在 Clojure 中:

(map #(clojure.string/split  % #"\s+") ["two birds" "with one stone"])
;; => (["two" "birds"] ["with" "one" "stone"])

(mapcat #(clojure.string/split  % #"\s+") ["two birds" "with one stone"])
;; => ("two" "birds" "with" "one" "stone")