球拍地图笛卡尔产品的东西

时间:2015-01-04 21:31:16

标签: dictionary racket cartesian-product

在球拍中,在两个列表中使用的高阶函数(如地图)就是这样:

(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 个答案:

答案 0 :(得分:3)

这是一种完全使用高阶函数的方法(foldrappend-mapmap;现在也使用compose1currycurryr):

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

请原谅可怕的参数名称。有一天,我会想出一些好的东西。 : - )

答案 1 :(得分: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

答案 2 :(得分:2)

在SCIP第2.2.3章“作为常规界面的序列中,作者向我们展示了解决此类问题的一般方法。实际上有一个类似的例子。本书使用平面图作为一种常见的抽象。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))