由于两个数组都是按降序排列的,因此您只需选择第一个元素右侧的另一个元素,就可以保证这对数组的顺序。
显然你想对两个参数都这样做,并从它们中配对。
在部分不惯用的 Haskell 中(使用索引,因此它更接近于命令式伪代码);使用列表推导:
foo xs ys = [ -- list of
[ -- lists of
[ (x1,y1), (x2,y2) ] -- pairs of pairs, where
| (j,y1) <- jys, -- for each elt y1 in ys, pick each
y2 <- drop j ys -- y2 to the right of it in ys
]
| -- where
(i,x1) <- ixs, -- for each x1 in xs,
x2 <- drop i xs ] -- pick each x2 to the right of it in xs
where
ixs = zip [1..] xs -- make indexed pairs
jys = zip [1..] ys
运行它:
> foo [4,3,2,1] [30,20,10]
[ [[(4,30),(3,20)],[(4,30),(3,10)],[(4,20),(3,10)]] ,
[[(4,30),(2,20)],[(4,30),(2,10)],[(4,20),(2,10)]] ,
[[(4,30),(1,20)],[(4,30),(1,10)],[(4,20),(1,10)]] ,
[[(3,30),(2,20)],[(3,30),(2,10)],[(3,20),(2,10)]] ,
[[(3,30),(1,20)],[(3,30),(1,10)],[(3,20),(1,10)]] ,
[[(2,30),(1,20)],[(2,30),(1,10)],[(2,20),(1,10)]] ]
列表推导只是循环。
按照您的示例,这需要将其平展一层。这可以通过使用专门的展平功能(在 Haskell 中为 concat)进行后处理来实现,但也可以通过重新排列循环来实现:
bar xs ys = [ [ (x1,y1), (x2,y2) ]
| --
(i,x1) <- ixs, -- for each x1 in xs,
x2 <- drop i xs, -- pick each x2 to the right of x1 in xs
(j,y1) <- jys, -- and for each y1 in ys,
y2 <- drop j ys ] -- pick each y2 to the right of y1 in ys
where
ixs = zip [1..] xs -- make indexed pairs
jys = zip [1..] ys
----
----
> bar [4,3,2,1] [30,20,10]
[ [(4,30),(3,20)],[(4,30),(3,10)],[(4,20),(3,10)],
[(4,30),(2,20)],[(4,30),(2,10)],[(4,20),(2,10)],
[(4,30),(1,20)],[(4,30),(1,10)],[(4,20),(1,10)],
[(3,30),(2,20)],[(3,30),(2,10)],[(3,20),(2,10)],
[(3,30),(1,20)],[(3,30),(1,10)],[(3,20),(1,10)],
[(2,30),(1,20)],[(2,30),(1,10)],[(2,20),(1,10)] ]
这就是你想要的。