可能重复:
F# - cross product of two lists
Projecting a list of lists efficiently in F#
我有一个带有两个整数列表的函数,并返回一个包含所有笛卡尔积的列表。我认为我有正确的想法,但没有正确的实施。我可以得到一些指示吗?
let rec cartesian = function
| ([],[]) -> []
| (xs,[]) -> []
| ([],ys) -> []
| (x::xs,ys) -> List.map(fun y -> (x,y)::[]) cartesian (xs,ys)
答案 0 :(得分:10)
这是一个快速修复:
let rec cartesian = function
| ([],[]) -> []
| (xs,[]) -> []
| ([],ys) -> []
| (x::xs, ys) -> (List.map(fun y -> x,y) ys) @ (cartesian (xs,ys))
我们的想法是,对于每个元素x
,您生成一个列表[(x, y1); (x, y2); ...; (x, yn)]
并将这些列表连接起来。
在您的函数中,第一个模式匹配情况是多余的。并且参数更加便于以咖喱形式存在。该功能可能如下所示:
let rec cartesian xs ys =
match xs, ys with
| _, [] -> []
| [], _ -> []
| x::xs', _ -> (List.map (fun y -> x, y) ys) @ (cartesian xs' ys)
一旦理解了这个想法,就会发现高阶函数List.collect
与任务完全匹配:
let cartesian xs ys =
xs |> List.collect (fun x -> ys |> List.map (fun y -> x, y))