Da die Frage aufkam, warum
fold sich anders bzgl. Laziness verhält als
nub, d.h., nicht bereits Teilergebnisse liefert: das hängt ganz von der als Operator verwendeten Liste ab. Im Beispiel, das in der Übung betrachtet wurde, ist das allerdings so; die (duplikatfreie) Ergebnisliste steht erst am Schluss der Auswertung "am Stück" zur Verfügung.
Als vereinfachtes Bespiel (habe (:) statt (++) benutzt, da es auf die Reihenfolge der Element im Resultat nicht wirklich ankommt) kann folgender Ausdruck dienen:
Code: Alles auswählen
foldl (\as b -> if b `elem` as then as else b:as) [] [1, 2, 1]
Dieser expandiert (unter freier Interpretation des Backtick-Operators) zu:
Code: Alles auswählen
((([] `\as b -> if b `elem` as then as else b:as` 1)
`\as' b' -> if b' `elem` as' then as' else b':as'` 2)
`\as'' b'' -> if b'' `elem` as'' then as'' else b'':as''` 1)
Die Evaluation wird nun gemäß der Klammerung zuerst in der untersten Zeile erzwungen:
b'' ist offensichtlich 1 aber über den Wert von
as'' kann man noch nichts sagen; dazu muss erst der Teilausdruck in den Zeilen 1-2 zumindest partiell ausgewertet werden. Zumindest partiell deshalb, weil
b'' `elem` as'' (wenn
as'' nicht leer ist) frühestens nach dem ersten Element mit einem Treffer abbrechen kann. Hier wiederholt sich das Spiel und der Teilausdruck in Zeile 1 wird ausgewertet (zu
[1]).
Wenn man nun bedenkt, dass alle Listenelemente von der Konsole stammen, ist klar, dass Fold (ob
foldl oder
foldr ist hier egal) hier kein Ergebnis liefern kann, bevor nicht die gesamte Eingabe getätigt wurde, d.h., die gesamte Liste bekannt ist.
Hoffe, das bringt etwas Licht ins Dunkel.