Ich versuche Tail-Rekursion in Haskell zu verstehen. Ich denke, ich verstehe, was es ist und wie es funktioniert, aber ich möchte sicherstellen, dass ich die Dinge nicht vermassle. HierTail Rekursion in Haskell
ist die "Standard" faktorielles Definition:
factorial 1 = 1
factorial k = k * factorial (k-1)
Beim Laufen, beispielsweise factorial 3
, meine Funktion ruft mich 3-mal (geben oder nehmen). Dies könnte ein Problem darstellen, wenn ich Faktor 99999999 berechnen möchte, da ich einen Stapelüberlauf haben könnte. Nachdem ich factorial 1 = 1
erreicht habe, muss ich im Stack "zurückkommen" und alle Werte multiplizieren, also habe ich 6 Operationen (3 für den Aufruf der Funktion selbst und 3 für die Multiplikation der Werte).
Jetzt präsentieren Sie ich eine weitere mögliche Implementierung faktorielles:
factorial 1 c = c
factorial k c = factorial (k-1) (c*k)
Dieser rekursiv ist, auch. Es wird sich 3 Mal selbst anrufen. Aber es hat nicht das Problem, dann noch "zurückkommen" zu müssen, um die Multiplikationen aller Ergebnisse zu berechnen, da ich bereits das Ergebnis als Argument der Funktion übergebe.
Dies ist, was ich verstanden habe, was Tail Recursion ist. Jetzt scheint es ein bisschen besser als das erste, aber Sie können Stapelüberläufe immer noch so leicht haben. Ich habe gehört, dass der Haskell-Compiler Tail-Recursive-Funktionen hinter den Kulissen in for-Schleifen umwandelt. Ich denke, das ist der Grund, warum es sich lohnt, tail rekursive Funktionen zu machen?
Wenn das der Grund ist, dann gibt es absolut keine Notwendigkeit, zu versuchen, Funktionen tail rekursiv zu machen, wenn der Compiler diesen klugen Trick nicht macht - habe ich Recht? Zum Beispiel, obwohl der C# -Compiler theoretisch tail rekursive Funktionen in Loops erkennen und konvertieren könnte, weiß ich (zumindest ist das, was ich gehört habe), dass es das derzeit nicht tut. Es macht also absolut keinen Sinn, die Funktionen tail-rekursiv zu machen. Ist es das?
Danke!
nur darauf hin, dass die "Standard" faktorielles Definition ist 'faktorielles 0 = 1 ' – irrelephant
Ja, ich thoug ht davon aber Faktor 1 = 1 ist effizienter. –
Sie wissen, dass das Speichern eines einzigen Iterationsschritts wahrscheinlich das letzte ist, worüber Sie sich bei der Berechnung von Faktoren Gedanken machen müssen. Auch, wenn Sie versuchen, 99999999 zu berechnen! Ich bin mir ziemlich sicher, dass Stack-Überläufe das geringste Ihrer Probleme sein werden. –