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?
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:
Dies ist ziemlich ähnlich zu dem oben, aber mit einem zusätzlichen runWriter
geworfen; Zum Beispiel könnten Sie eines dieser beiden schreiben:
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.
Jede Funktion, die I / O ausführt, muss ihr Ergebnis in der IO
monad:
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.
Aufbauend auf @ is7s 'Antwort ist ein nützliches Idiom für Debug.Trace
, dies zu tun:
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.