如何在Racket中使用append-map(Scheme)

imk*_*dal 6 scheme procedural-programming procedures racket

我不完全理解append-map命令在球拍中的作用,也不了解如何使用它,我很难在线找到一些体面可理解的文档.有人可能会证明命令究竟是什么以及它是如何工作的?

Ósc*_*pez 10

append-map程序是用于创建单个列表出子列表的列表的有用之后施加步骤可以将每个子列表.换句话说,这段代码:

(append-map proc lst)
Run Code Online (Sandbox Code Playgroud)

...在语义上等同于:

(apply append (map proc lst))
Run Code Online (Sandbox Code Playgroud)

... 或这个:

(append* (map proc lst))
Run Code Online (Sandbox Code Playgroud)

应用附加到子列表的成语列表有时被称为展子列表列表.让我们来看看一些例子,这是一个正确的位置的文件中:

(append-map vector->list '(#(1) #(2 3) #(4)))
'(1 2 3 4)
Run Code Online (Sandbox Code Playgroud)

有关更有趣的示例,请查看Rosetta Code 中的此代码,以查找列表的所有排列:

(define (insert l n e)
  (if (= 0 n)
      (cons e l)
      (cons (car l) 
            (insert (cdr l) (- n 1) e))))

(define (seq start end)
  (if (= start end)
      (list end)
      (cons start (seq (+ start 1) end))))

(define (permute l)
  (if (null? l)
      '(())
      (apply append (map (lambda (p)
                           (map (lambda (n)
                                  (insert p n (car l)))
                                (seq 0 (length p))))
                         (permute (cdr l))))))
Run Code Online (Sandbox Code Playgroud)

使用以下方法可以更简洁地表达最后一个程序append-map:

(define (permute l)
  (if (null? l)
      '(())
      (append-map (lambda (p)
                    (map (lambda (n)
                           (insert p n (car l)))
                         (seq 0 (length p))))
                  (permute (cdr l)))))
Run Code Online (Sandbox Code Playgroud)

无论哪种方式,结果如预期:

(permute '(1 2 3))
=> '((1 2 3) (2 1 3) (2 3 1) (1 3 2) (3 1 2) (3 2 1))
Run Code Online (Sandbox Code Playgroud)