Ist es möglich, den GHCi-Debugger zu stoppen, wenn das Ergebnis einer Funktion bekannt ist?
Betrachten Sie zum Beispiel das folgende Code-Snippet:
%Vor%Nun möchte ich die Ergebnisse von 'pappperlap' und 'bla' sehen. Aber denken Sie daran, ich möchte aufhören, wenn das Ergebnis ausgewertet wird. Die Verwendung von ': force' kommt daher nicht in Frage, da sie die Reihenfolge der Auswertung ändert.
Wenn ich ': break' verwende, stoppt der Debugger, aber _result wird noch nicht ausgewertet. Nachfolgend finden Sie meine GHCi-Sitzung, die nicht die gewünschten Zwischenergebnisse liefert:
%Vor%Könnte etwas zu spät für Ihre unmittelbaren Debugging-Probleme sein, aber hier ist, was ich tun würde:
%Vor% Jetzt wissen wir, dass wir eine Ausnahme in der Auswertung von bla
bekommen werden. Lass uns also in ghci fallen:
Und so können wir sehen, dass der Stack zur Auswertung der rechten Seite von bla
führt.
Das ist nicht perfekt, da das Einfügen in undefined
s überall schäbig und hacky aussieht, aber :hist
gibt dir schon eine Menge Arbeit, und die Verwendung von :list
, wenn du zurücktrittst, macht die Dinge noch klarer.
Haskell durchläuft keine wörtlichen Ausdrücke für Sie. Etwas wie
%Vor%wird sofort zu 8 ausgewertet, weil der Compiler alle Ausdrücke optimiert, die aus Literalen bestehen, die zur Kompilierungszeit nur "herumliegen" (diese Art von Ausdruck wird als konstante Anwendungsform bezeichnet).
Jetzt müssen Sie erkennen, dass foldl
faul ist. Wenn Sie foldl f
in einer Liste aufrufen, wird keine einzelne Auswertung von f
durchgeführt, bis Sie dazu gezwungen sind.
schließlich haben wir ((0+1)+2)+3)
und der Compiler sagt "ok, wir haben jede Liste ausgeschöpft und jede Auswertung auf die primitivste Form erweitert, die wir können. Lass uns auswerten." Und wir wissen bereits, dass Haskell nicht die Bewertung einer CAF durchläuft.
Wenn Sie die Zwischenwerte der Auswertung sehen wollen, müssen Sie diese zuerst erstellen. Die Art, wie Sie dies tun, ist die folgende strikte Variante von foldl
:
Ich werde Sie verlassen, um herauszufinden, wie es funktioniert, aber seq a b
wird a
vollständig auswerten, bevor Sie fortfahren, b
faul auszuwerten.
Alles andere wie zuvor, außer dass foldl
in foldl'
geändert wird. Wenn Sie die Evaluierung durchlaufen, sehen Sie eine Zwischenstufe, wenn Sie in der foldl'
-Funktion angehalten werden.
Tags und Links haskell debugging lazy-evaluation