In Haskell, wenn ichAkkumulatoren in Haskell
fac n = facRec n 1
where facRec 0 acc = acc
facRec n acc = facRec (n-1) (acc*n)
und kompilieren Sie es mit GHC schreiben, wird das Ergebnis anders sein, als wenn ich verwendet
fac 0 = 1
fac n = n * fac (n-1)
ich leicht fac n = product [1..n]
tun könnte und vermeiden die Ganze Sache, aber ich interessiere mich dafür, wie ein Versuch der Tail-Rekursion in einer faulen Sprache ausgeht. Ich bekomme, dass ich immer noch einen Stack-Overflow bekomme, weil sich Thunks aufbauen, aber passiert tatsächlich etwas anders (in Bezug auf das resultierende kompilierte Programm), wenn ich einen Akkumulator verwende, als wenn ich gerade die naive Rekursion feststelle? Gibt es einen Vorteil, die Tail-Rekursion außer einer besseren Lesbarkeit zu vernachlässigen? Ändert sich die Antwort überhaupt, wenn ich runhaskell
verwende, um die Berechnung auszuführen, anstatt sie zuerst zu kompilieren?
Was ist Ihre Definition von "passiert eigentlich alles anders?"? Die triviale Antwort ist "Ja", weil sie _ein_ verschieden sind - der eine ist rekursiv und der andere nicht. Aber ich glaube nicht, dass du das fragst ..? – lijie
meinst du nicht facRec n acc = facRec (n-1) (acc * n) ???? –
@lijie - Ich bin hauptsächlich daran interessiert, ob GHC Tail-Call-Optimierung (mit oder ohne Akku), aber ich habe es allgemein, weil ich ehrlich gesagt nicht sicher bin, wie Schwanz Rekursion mit faulen Sprachen interagiert, und es kann auch anders Dinge basieren auf meiner Verwendung einer Form gegenüber einer anderen. Ich weiß nicht, was diese anderen Dinge sind. – Inaimathi