use*_*706 4 f# f#-interactive f#-scripting
可能重复:
F# - 两个列表的交叉乘积
在F#中有效地投影列表列表
我有一个函数,它接受两个整数列表,并返回一个包含所有笛卡儿积的列表.我认为我有正确的想法,但没有正确的实施.我可以得到一些指示吗?
let rec cartesian = function
| ([],[]) -> []
| (xs,[]) -> []
| ([],ys) -> []
| (x::xs,ys) -> List.map(fun y -> (x,y)::[]) cartesian (xs,ys)
Run Code Online (Sandbox Code Playgroud)
pad*_*pad 11
这是一个快速修复:
let rec cartesian = function
| ([],[]) -> []
| (xs,[]) -> []
| ([],ys) -> []
| (x::xs, ys) -> (List.map(fun y -> x,y) ys) @ (cartesian (xs,ys))
Run Code Online (Sandbox Code Playgroud)
我们的想法是,使用每个元素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)
Run Code Online (Sandbox Code Playgroud)
一旦理解了这个想法,就会发现高阶函数List.collect
与任务完全匹配:
let cartesian xs ys =
xs |> List.collect (fun x -> ys |> List.map (fun y -> x, y))
Run Code Online (Sandbox Code Playgroud)