在球拍中,在两个列表中使用的高阶函数(如地图)就是这样:
(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) )
我怎样才能做到这一点?最好具有更高阶函数?
答案 0 :(得分: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))
请原谅可怕的参数名称。有一天,我会想出一些好的东西。 : - )
答案 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))
答案 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))