2013-01-31 3 views
4

Я не совсем понимаю, что делает команда append-map в racket, и я не понимаю, как ее использовать, и мне очень трудно найти некоторые прилично понятную документацию онлайн. Может ли кто-нибудь продемонстрировать, что именно делает команда и как она работает?Как использовать append-map в Racket (Scheme)

ответ

9

Процедура append-map полезна для создания единого списка из списка подписок после, применяя процедуру для каждого подсети. Другими словами, этот код:

(append-map proc lst) 

... семантически эквивалентно следующему:

(apply append (map proc lst)) 

... Или это:

(append* (map proc lst)) 

подающая заявку-Append-to a-list-of-sublists idiom иногда называется сглаживает список подписок. Давайте рассмотрим несколько примеров, это одно право here в документации:

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

Для более интересного примера, посмотри на этом code от Rosetta кодекса для поиска всех перестановок списка:

(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)) 
3

В Common Lisp, функция называется "mapcan" и иногда используется для объединения фильтрации с отображением:

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

В Ракетка это было бы:

> (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) 
Смежные вопросы