Haskell Drucken während der Rekursion?

8
%Vor%

Wie würden Sie jedes Mal, wenn es von sich selbst aufgerufen wird, eine Ausgabe ausgeben (die Ganzzahl z)? Können Sie eine Funktion haben, die ein IO und Int zurückgibt? Brauchen Sie eine sekundäre Funktion?

    
ArchHaskeller 24.03.2012, 03:15
quelle

4 Antworten

19

Der Einfachheit halber können Sie trace . Es ist jedoch nicht für echten Produktionscode erwünscht, da es referentielle Transparenz verletzt. trace benötigt einen String zum Drucken und einen Wert zum Zurückgeben.

%Vor%     
is7s 24.03.2012, 04:51
quelle
10

Der Vollständigkeit halber werde ich diese Frage beantworten:

  

Können Sie eine Funktion haben, die IO und Int zurückgibt?

... ganz wörtlich. Die Antwort ist "Ja!" ... und manchmal sogar nützlich. Wahrscheinlich ist das nicht das, was du als Anfänger machen willst, aber falls es so ist, hier ist ein Beispiel.

%Vor%

Sie können beispielsweise die rekursiven Aufrufe durch Setzen von

drucken %Vor%

oder Sie können die Antwort einfach ausdrucken, indem Sie

einstellen %Vor%

oder ein halbes Dutzend anderer Dinge. Natürlich ist der IO () Typ ein wenig schwer zu inspizieren; Sie könnten stattdessen folgendes schreiben:

%Vor%

Dies ist ziemlich ähnlich zu dem oben, aber mit einem zusätzlichen runWriter geworfen; Zum Beispiel könnten Sie eines dieser beiden schreiben:

%Vor%

Der Vorteil dieser Methode besteht darin, dass Sie eine Liste von Aufrufwerten zurückerhalten, anstatt eine IO-Aktion, die diese Liste druckt, so dass Sie die Aufrufe auf viel interessantere Weise verschieben können.

    
Daniel Wagner 24.03.2012 07:00
quelle
4

Jede Funktion, die I / O ausführt, muss ihr Ergebnis in der IO monad:

zurückgeben %Vor%

Beachten Sie, dass beide Zweige des Ausdrucks if jetzt auch in IO sein müssen.

Dies ist nicht dasselbe wie die Rückgabe von "an IO und Int ". IO Int ist der Typ eines Werts, der eine E / A-Aktion darstellt, die bei ihrer Ausführung ein Int als Ergebnis liefert (möglicherweise nach einigen E / A). Die obige Definition von foo nimmt also Int und Int und gibt eine I / O-Aktion zurück, die schließlich zu Int führt.

    
bitbucket 24.03.2012 03:28
quelle
3

Aufbauend auf @ is7s 'Antwort ist ein nützliches Idiom für Debug.Trace , dies zu tun:

%Vor%

Hier haben wir eine Definition von foo mit der trace in einem Guard eingeführt, die zu False ausgewertet wird, so dass sie immer auf die ursprüngliche Definition fällt. Auf diese Weise stören wir unsere Funktion nicht und können die Ablaufverfolgung ein- oder ausschalten, indem Sie die Zeile auskommentieren.

    
pat 24.03.2012 16:13
quelle

Tags und Links