flatmap最直接的用法

Most direct usage of flatmap

我已经编写了一个 map 和一个 flatmap 函数,我正在尝试找出查看平面图函数如何独立运行的最佳方法。这是我的两个定义:

(define (map function lst)
  (if (null? lst)
      ; if we have reached the end of the list, return an empty list
      ; this essentially terminates the list that we are adding below with the cons
      nil
      ; we do a cons -- with the scalar produced by the function call on the current element
      ;                 and the list proceduced by passing the rest of the elements again to the map function
     (cons (function (car lst)) (map function (cdr lst)))))
(define (flatmap function lst)
  (if (null? lst)
      nil
      ; really the only difference here is we do an append instead of a cons
      (append (function (car lst)) (flatmap function (cdr lst)))))

并且调用 map 非常简单,我只是向它传递一个接受单个参数(列表元素)的函数:

(map (lambda (x) (* x x)) '(1 2 3 4 5))
; (1 4 9 16 25)

但是,我很难想出一个示例 input/function,我可以将其直接传递给 flatmap 函数以查看其工作原理。有什么例子可以直接说明它是如何工作的?

任何接受单个参数和 returns 列表的函数都可以。这是您用来演示 map.

的函数的变体
(flatmap (lambda (x) (list x (* x x))) '(1 2 3 4 5))
; (1 1 2 4 3 9 4 16 5 25)

这里有几个例子:

;;; flattening a list by one-level
(flatmap (lambda (p) p) '((1 2 3) (4 5 6)))
;(1 2 3 4 5 6)
(flatmap (lambda (p) p) '((1 2 (3 4) 5) (6 7 8)))
; (1 2 (3 4) 5 6 7 8)
;;; Map-and-flatten a list at once
(flatmap
    (lambda (p) (cons (* 2 (car p)) 
                      (list (* 2(cadr p))) )) 
    '((1 2) (3 4)))
; (2 4 6 8)
; Or could be done with a combination of the two which reads more simply:
(map (lambda (x) (* x 2)) 
     (flatmap (lambda (p) p) '((1 2) (3 4))))
; (2 4 6 8)
;; Possible to do something like (flatmap (lambda (x) (map... ?) to accomplish same?

虽然上面的大部分只是使用 lambda (p) p 身份,但我猜整体上看起来没什么用......

也许一个真正有用的递归扁平化列表:

(define (flat lst)
  (flatmap (lambda (x) (if (pair? x) (flat x) (list x))) lst))

(flat '(1 2 3 (1 (2 3 (5 5 5) 4) 3)))
; (1 2 3 1 2 3 5 5 5 4 3)