2013-06-10 2 views
13

Repeat is defined wie folgt:Warum ist die Wiederholung in Prelude so definiert?

repeat :: a -> [a] 
repeat x = xs where xs = x:xs 

Gibt es einen Grund, dass die folgenden verwendet wird, nicht?

repeat :: a -> [a] 
repeat x = x : repeat x 

(Offensichtlich gibt es viele äquivalente Definitionen für viele Prelude Funktionen, aber meine letztere Beschreibung nur fühlt sich viel mehr auf der Hand. Ich frage mich, ob eine Leistung oder Stil Grund für die Art und Weise gibt es es ist.)

+6

[Siehe meine Antwort hier] (http://stackoverflow.com/questions/16632143/why-recursive-let-make-space-effcient/16632403#16632403). Die Definition dort verwendet 'Let', aber es ist das gleiche Verhalten mit' Where'. – hammar

Antwort

20

Es ist aus Gründen der Performance und der Raumkomplexität.

Die erste Version des Codes verwendet explizite Freigabe; Es sieht im Grunde aus wie eine kreisförmige Liste mit einem Element im Speicher (xs im Code ist ein Listenknoten, der x als Wert hat und dessen Endpunkte auf den gleichen Listenknoten zeigen). Wenn Sie mehr und mehr Elemente der Liste auswerten, wird immer nur derselbe Knoten wiederholt.

Im Gegensatz dazu erstellt die zweite Version eine Liste, die tatsächlich im Speicher wächst, während sie ausgewertet wird, da verschiedene Aufrufe von repeat x immer neu berechnet (und nicht protokolliert) werden. Am Ende der generierten Liste wird immer ein weiterer unbewerteter Thunk liegen.

Verwandte Themen