2015-01-04 2 views
2

В ракетке более высокая функция заказа, как карты, используемой в двух списках делает это:Ракетка карта декартово произведение вещь

(map list '(1 2 3) '(1 2 3)) 
> '((1 1) (2 2) (3 3)) 

Но я хотел бы декартово-продукт вещь, как это:

'((1 1) (1 2) (1 3) (2 1) (2 2) (2 3) (3 1) (3 2) (3 3)) 

Как могу ли я достичь этого? Предпочтительно с функциями более высокого порядка?

ответ

3

Вот метод, который полностью использует функцию высшего порядка (foldr, append-map и map, а теперь и с compose1, curry и curryr):

(define (cartesian-product . lists) 
    (foldr (lambda (a b) 
      (append-map (compose1 (curryr map b) (curry cons)) 
         a)) 
     '(()) 
     lists)) 

помилованием страшных именами параметров. Однажды я придумаю что-нибудь хорошее. :-)

3
> (require unstable/list) 
> (cartesian-product '(1 2 3) '(a b c)) 
'((1 a) (1 b) (1 c) (2 a) (2 b) (2 c) (3 a) (3 b) (3 c)) 

См http://docs.racket-lang.org/unstable/list.html#%28def._%28%28lib._unstable%2Flist..rkt%29._cartesian-product%29%29

+0

Ну, это нестабильное, что означает, что он не будет переносимым между версиями :-( –

+0

Я не ожидаю, что это уйти.: -) – soegaard

+0

Правильно, но требуемый импорт может измениться, поэтому ваш код по-прежнему не будет стабильным между версиями. ;-) –

2

В SCIP глава 2.2.3 «последовательности, как обычные интерфейсы, авторы показывают нам общий способ приблизиться к такой проблеме. Существует на самом деле подобный пример. В книге использована flatmap в качестве общей абстракции The combination of mapping and accumulating with append is so common in this sort of program that we will isolate it as a separate procedure: flatmap Вот решение с использованием flatmap:..

>(define (flatmap proc seq)                                  
    (foldr append '() (map proc seq))) 
>(flatmap                                 
    (lambda (x)                                
    (map                                 
     (lambda (y) (list y x))                            
     '(1 2 3)))                                
    '(a b c))                                 
'((1 a) (2 a) (3 a) (1 b) (2 b) (3 b) (1 c) (2 c) (3 c))  
Смежные вопросы