2009-08-26 10 views
1

den folgenden C# -Code Gegeben:F # - wie verschachtelte Schleifen rekursiv geschrieben werden?

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

Was das Äquivalent F # -Code in einem funktionalen Stil geschrieben sein würde?

+0

Ich weiß nicht, F #, aber ich kenne andere funktionale Sprachen, und ich kann ein wenig Ratschlag bieten: Konvertieren Sie die innere (mehr verschachtelte) Schleife in eine rekursive Funktion zuerst. Dann sollte es einfacher sein, die äußere Schleife in eine rekursive Funktion umzuwandeln, die die innere Schleifenfunktion aufruft. – Imagist

Antwort

5

die Lösung, die Brian vorschlägt, ist definitiv die beste Option (in F #). Mithilfe von Sequenzausdrücken können Sie leichter ausdrücken, was Sie meinen. Warum also nicht verwenden?

Wie auch immer, wenn Sie dies tun, nur als Übung, dann können Sie die verschachtelte Schleife als einzelne rekursive Funktion und die äußere Schleife als zweite neu schreiben (wie Imagist schon sagt):

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) 

Ich bin Verwenden von :: in der verschachtelten Funktion zum Anhängen von Elementen an den Anfang und @ zum Verketten von Listen, die von einzelnen verschachtelten Funktionsaufrufen generiert wurden. Die Verwendung von @ ist nicht sehr effizient, und der Code ist auch nicht Schwanz-rekursiv, so bessere Version Akkumulator Parameter verwendet würde wie folgt aussehen:

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 

hoffte, das hilft!

13

Ich würde es nur so mit den for-Schleifen schreiben. Selbst ein Haskell-Programmierer würde dies wahrscheinlich mit einem Listenverständnis ausdrücken, in welchem ​​Fall Sie z.B.

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

in F #.

+0

Sie verpassen syntaktischen Zucker, obwohl ich denke, dass es in dieser Situation nicht angemessen ist. (-> == Ausbeute) lost productsList = [für x in 2 .. 4 tun für y in 2..4 -> x * y] –

Verwandte Themen