2009-08-26 89 views
1

下面的C#代码:F# - 如何以递归方式编写嵌套循环?

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

什么是写在一个实用的风格等效F#代码?

+0

我不知道F#,但我知道其他函数式语言,我可以提供一些建议:首先将内部(更多嵌套)循环转换为递归函数。然后,将外部循环转换为调用内部循环函数的递归函数应该更容易。 – Imagist 2009-08-26 16:01:29

回答

5

布赖恩建议的解决方案绝对是最好的选择(在F#中)。序列表达式让你更容易表达你的意思,所以为什么不使用它们?

无论如何,如果你这样做只是作为一个锻炼; Tibial,那么你可以重写嵌套循环单递归函数和外环的第二(如意象建议):

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 

希望这有助于!

13

我只是用for-loops这样写的。即使是Haskell程序员也可能会用列表理解来表达,在这种情况下,您可以编写例如

let productsList = 
    [for x in 2..4 do 
    for y in 2..4 do 
    yield x*y] 

in F#。

+0

你错过了语法糖,但我认为这不适合这种情况。 ( - > == do yield) let productsList = [for x in 2 .. 4 do for y in 2..4 - > x * y] – 2009-08-27 18:57:32