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