Wie kann ich eine tail-rekursive Liste anhängen?

8

Eine einfache Append-Funktion wie diese (in F #):

%Vor%

stürzt ab, wenn s groß wird, da die Funktion nicht tail rekursiv ist. Ich habe bemerkt, dass F # 's Standard Append-Funktion nicht mit großen Listen abstürzt, also muss es anders implementiert werden. Also fragte ich mich: Wie sieht eine rekursive Definition von Append aus? Ich habe mir so etwas ausgedacht:

%Vor%

das funktioniert, sieht aber eher komisch aus. Gibt es eine elegantere Definition?

    
martingw 19.05.2010, 16:33
quelle

3 Antworten

26

Traditionell (nicht tail-rekursiv)

%Vor%

Mit einem Akkumulator (tail-recursive)

%Vor%

Mit Fortsetzungen (tail-recursive)

%Vor%

Es ist ziemlich einfach, jede nicht-tail rekursive Funktion in rekursive mit Fortsetzungen zu konvertieren, aber ich persönlich bevorzuge Akkus für einfache Lesbarkeit.

    
Juliet 19.05.2010, 16:52
quelle
14

Zusätzlich zu dem, was Julia gepostet hat:

Verwenden von Sequenzausdrücken
Intern erzeugen Sequenzausdrücke tail-rekursiven Code, was gut funktioniert.

%Vor%

Verwenden von veränderbaren .NET-Typen
David erwähnte, dass F # -Listen mutiert werden können - dies ist jedoch nur auf F # -Kernbibliotheken beschränkt (und die Funktion kann nicht von Benutzern verwendet werden, da sie die funktionalen Konzepte durchbricht). Sie können veränderbare .NET-Datentypen verwenden, um eine auf Mutationen basierende Version zu implementieren:

%Vor%

Dies kann in einigen Szenarien nützlich sein, aber ich würde generell Mutationen im F # -Code vermeiden.

    
Tomas Petricek 19.05.2010 17:44
quelle
1

Aus einem kurzen Blick auf die F # -Quellen scheint der Schwanz innerlich veränderbar zu sein. Eine einfache Lösung wäre, die erste Liste umzukehren, bevor ihre Elemente in die zweite Liste eingefügt werden. Das, zusammen mit der Umkehrung der Liste, ist trivial, Schwanz rekursiv zu implementieren.

    
Daniel 19.05.2010 16:56
quelle

Tags und Links