我是f新手#用F#计算笛卡尔乘积列表的乘积
我试着计算笛卡尔乘积的列表中的乘积。我“借”这个。
let xs = [1..99]
let ys = [1..99]
seq {for x in xs do for y in ys do yield x * y}
有没有更好或更优雅的方式?
加里
我是f新手#用F#计算笛卡尔乘积列表的乘积
我试着计算笛卡尔乘积的列表中的乘积。我“借”这个。
let xs = [1..99]
let ys = [1..99]
seq {for x in xs do for y in ys do yield x * y}
有没有更好或更优雅的方式?
加里
另一个possibiltiy基于列表模块提供的是功能来解决这个问题:
let xs = [1..99]
let ys = [1..99]
let zs = xs |> List.collect (fun x -> ys |> List.map (fun y -> x*y))
避免了额外要求,以.concat,也应该做的工作。
但我会坚持你的解决方案。它应该是最可读的,它是一个真正的匹配者。 (只是试着大声地读出代码,你完全可以理解,而Noldorins或我的不是)
的确有一个稍微更优雅的方式(至少在功能意义上)来计算笛卡尔乘积,其使用存在于List
类内的功能。 (有没有必要让序列或环这里,至少不是直接)
试试这个:
let xs = [1..99]
let ys = [1..99]
xs |> List.map(fun x -> ys |> List.map(fun y -> x * y)) |> List.concat
稍长无可否认,尽管功能更强大的风格,它似乎。
声明:我没有安装当前F#的机器,所以我无法测试我的代码。基本上,不过,如果你从哈斯克尔偷sequence
,你可以写你的程序作为
let cartesian = sequence >> List.map product
,并运行它
cartesian [[1..99]; [1..99]]
下面是如何写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 (*)
然后,你可以写你的程序作为
let cartesian xs ys = [xs; ys] |> sequence |> List.map product
// ... or one-argument, point-free style:
let cartesian' = sequence >> Seq.map product
您可能需要改变一些Seq
s到List
秒。
但是,能够猜出非一般列表理解含义的人数可能比识别名称sequence
多很多,所以你可能比列表理解更好。 sequence
随时可以运行整个计算表达式列表。
相关问题在这里:http://stackoverflow.com/questions/482866/f-cross-product-of-two-lists – Benjol 2009-06-02 06:56:56