Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 用F计算数列的笛卡尔积#_F# - Fatal编程技术网

F# 用F计算数列的笛卡尔积#

F# 用F计算数列的笛卡尔积#,f#,F#,我不熟悉f# 我试图计算一系列数字的笛卡尔积。我“借”了这个 有更好或更优雅的方式吗 Gary确实有一种稍微优雅的方法(至少在函数意义上)来计算笛卡尔积,它使用列表类中存在的函数。(这里不需要涉及序列或循环,至少不需要直接涉及。) 试试这个: let xs = [1..99] let ys = [1..99] xs |> List.map(fun x -> ys |> List.map(fun y -> x * y)) |> List.concat 诚然,虽然样式

我不熟悉f#

我试图计算一系列数字的笛卡尔积。我“借”了这个

有更好或更优雅的方式吗


Gary

确实有一种稍微优雅的方法(至少在函数意义上)来计算笛卡尔积,它使用
列表
类中存在的函数。(这里不需要涉及序列或循环,至少不需要直接涉及。)

试试这个:

let xs = [1..99]
let ys = [1..99]
xs |> List.map(fun x -> ys |> List.map(fun y -> x * y)) |> List.concat

诚然,虽然样式上更具功能性,但时间稍长。

基于列表模块提供的功能解决此问题的另一种可能性是:

let xs = [1..99]
let ys = [1..99]
let zs = xs |> List.collect (fun x -> ys |> List.map (fun y -> x*y))
这样就避免了对.concat的额外调用,也应该完成这项工作


但我会坚持你的解决方案。它应该是最具可读性的,才是真正的赢家。(试着大声读出代码。你的代码完全可以理解,而诺多林或我的代码则不能。)

免责声明:我没有安装了当前F#的机器,因此我无法测试我的代码。不过,基本上,如果您从Haskell那里窃取
序列
,您可以将程序编写为

let cartesian = sequence >> List.map product
let cartesian xs ys = [xs; ys] |> sequence |> List.map product
// ... or one-argument, point-free style:
let cartesian' = sequence >> Seq.map product
并将其作为

cartesian [[1..99]; [1..99]]
下面是如何编写
序列
。这是你写的序列表达式的泛化版本。它只处理无限数量的列表:
{forx 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 = sequence >> List.map product
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
s


然而,能够猜出你的非一般列表理解的含义的人的数量可能远远超过能够识别名称
序列的人,因此你可能更擅长列表理解<代码>序列
在任何时候你想要运行整个计算表达式列表时都会派上用场。

啊,我想知道
mapcontat
方法去了哪里!在最新版本中,它似乎被重命名为
collect
。关于我们每个解决方案的可理解性/可读性,我认为这有点主观。我们当然提供了更典型的“功能性”解决方案,而OP建议了一个(非常好的)使用典型的“命令式”结构的解决方案。我怀疑有功能背景的人会发现我们的两种方法都更清晰。实际上,在我看来,问题中的代码比您的代码更接近列表理解。你的更像是列表理解的简化版。是的,实际上我不是指列表理解-我不确定它是否有一个特殊的名称,但我指的是列表。*函数。你能详细说明你所说的“不需要涉及序列”是什么意思吗,我不明白使用List.map而不是Seq.map有什么好处?@thinkhard:F#中的Seq类型实际上只是.NET中IEnumerable的别名,还有一些附加功能(例如
map
)。通过使用
Seq.map
,您实际上是在重复列表,就像使用
IEnumerable
一样,而当使用
list.map
时,您专门将其视为一个链表,因此不会增加iterables的开销(和间接性)。这里的相关问题:您会注意到我避免说“monad”。“计算表达式”仍然不如“温暖模糊的东西”那么友好