6

ラケットでappend-mapコマンドが何をするのか完全には理解していませんし、その使い方も理解していません。オンラインで適切に理解できるドキュメントを見つけるのにかなり苦労しています。コマンドが正確に何をし、どのように機能するかを誰かが示すことができますか?

4

2 に答える 2

11

このプロシージャは、各サブリストにプロシージャを適用したappend-mapで、サブリストのリストから単一のリストを作成する場合に役立ちます。つまり、このコードは次のようになります。

(append-map proc lst)

...意味的にはこれと同等です:

(apply append (map proc lst))

...またはこれ:

(append* (map proc lst))

apply-append-to-a-list-of-sublists イディオムは、サブリストのリストを平坦化することとして知られています。いくつかの例を見てみましょう。これはドキュメントのここにあります。

(append-map vector->list '(#(1) #(2 3) #(4)))
'(1 2 3 4)

より興味深い例として、リストのすべての順列を見つけるための 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))))))

最後の手順は、次を使用してより簡潔に表現できます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)))))

いずれにせよ、結果は期待どおりです。

(permute '(1 2 3))
=> '((1 2 3) (2 1 3) (2 3 1) (1 3 2) (3 1 2) (3 2 1))
于 2013-01-31T02:10:45.493 に答える
4

Common Lisp では、関数は「mapcan」と名付けられ、フィルタリングとマッピングを組み合わせるために使用されることがあります。

* (mapcan (lambda (n) (if (oddp n) (list (* n n)) '()))
        '(0 1 2 3 4 5 6 7))
(1 9 25 49)

Racket では次のようになります。

> (append-map (lambda (n) (if (odd? n) (list (* n n)) '()))
            (range 8))
'(1 9 25 49)

しかし、次のようにしたほうがよいでしょう。

> (filter-map (lambda (n) (and (odd? n) (* n n))) (range 8))
'(1 9 25 49)
于 2013-01-31T06:36:04.693 に答える