使用F#计算数字列表的笛卡尔乘积

Gar*_*ary 6 f#

我是f#的新手

我试着计算一组数字的笛卡尔积.我"借"了这个.

let xs = [1..99]
let ys = [1..99]
seq {for x in xs do for y in ys do yield x * y}
Run Code Online (Sandbox Code Playgroud)

有更好或更优雅的方式吗?

加里

lee*_*een 9

根据List模块提供的功能解决问题的另一个可能性是:

let xs = [1..99]
let ys = [1..99]
let zs = xs |> List.collect (fun x -> ys |> List.map (fun y -> x*y))
Run Code Online (Sandbox Code Playgroud)

这避免了对.concat的额外调用,也应该完成这项工作.

但我坚持你的解决方案.它应该是最可读的,是真正的对手.(只是试着大声读出这些代码.你的完全可以理解,Noldorins或我的不是.)


Nat*_*ers 7

免责声明:我没有安装当前F#的机器,所以我无法测试我的代码.但是,基本上,如果你sequence从Haskell 窃取,你可以编写你的程序

let cartesian = sequence >> List.map product
Run Code Online (Sandbox Code Playgroud)

并运行它

cartesian [[1..99]; [1..99]]
Run Code Online (Sandbox Code Playgroud)

这是写作的方法sequence.它是您编写的序列表达式的通用版本.它只处理无限数量的列表:{ for x in xs do for y in ys do for z in zs ... yield [x;y;z;...] }.

let rec sequence = function
  | [] -> Seq.singleton []
  | (l::ls) -> seq { for x in l do for xs in sequence ls do yield (x::xs) }
// also you'll need product to do the multiplication
let product = Seq.fold_left1 ( * )
Run Code Online (Sandbox Code Playgroud)

然后你可以编写你的程序

let cartesian xs ys = [xs; ys] |> sequence |> List.map product
// ... or one-argument, point-free style:
let cartesian' = sequence >> Seq.map product
Run Code Online (Sandbox Code Playgroud)

您可能需要将某些Seqs 更改为Lists.

但是,能够猜出非一般列表理解含义的人数可能比识别名称要多得多sequence,所以你可能更适合使用列表理解.sequence但是,只要您想运行整个计算表达式列表,它就会派上用场.