F# - 如何以递归方式编写嵌套循环?

时间:2009-08-26 15:49:45

标签: f# functional-programming nested-loops

给出以下C#代码:

var product = new List<int>();
for (int n1 = 100; n1 < 1000; n1++)
{
    for (int n2 = 100; n2 < 1000; n2++)
    {
        product.Add(n1 * n2);
    }
 }

以功能样式编写的等效F#代码是什么?

2 个答案:

答案 0 :(得分:16)

我会用for-loops以这种方式编写它。即使是Haskell程序员也可能用列表理解来表达这一点,在这种情况下你可以编写例如。

let productsList =
    [for x in 2..4 do
     for y in 2..4 do
     yield x*y]
在F#中

答案 1 :(得分:7)

Brian建议的解决方案绝对是最佳选择(在F#中)。序列表达式为您提供了一种更简单的方式来表达您的意思,为什么不使用它们呢?

无论如何,如果你这样做是为了练习,那么你可以将嵌套循环重写为单个递归函数,将外循环重写为第二个(如Imagist建议的那样):

let product = 
  let rec outer(n1) = 
    let rec nested(n2) = 
      if n2 > 4 then [] else (n1 * n2)::(nested(n2 + 1))
    if n1 > 4 then [] else nested(2) @ outer(n1 + 1)
  outer(2)

我在嵌套函数中使用::将元素追加到开头,@用于连接各个嵌套函数调用生成的列表。 @的使用效率不高,代码也不是尾递归的,所以使用累加器参数的更好的版本看起来像这样:

let product = 
  let rec outer n1 acc = 
    let rec nested n2 acc = 
      if n2 > 4 then acc else nested (n2 + 1) ((n1 * n2)::acc)
    if n1 > 4 then acc else outer (n1 + 1) (nested 2 acc)
  outer 2 [] |> List.rev

希望这有帮助!