Vorlesung: Praxis der Funktionalen Programmierung | Index

IO-Implementierung mit Streams

Nachdem wir gesehen haben, wie man die IO-Monade benutzt, betrachten wir eine mögliche Implementierung. Sowas ist normalerweise im jeweiligen Haskell-System versteckt (das war ja grad der Zweck der Monade, keine Details zu veröffentlichen).

Wir denken uns die zur Laufzeit bewegten Daten gesammelt in zwei Listen: einerseits die Liste der Fragen (bzw. Aufträge), die das Programm (bei seiner Ausführung) an das System stellt (erteilt), andererseits die Liste der Antworten, die das System dem Programm sagt.

Das Nutzer-Programm ist damit eine Funktion

f :: [ Antwort ] -> [ Frage ]
Die Reihenfolge ist kein Tippfehler! Aus der Liste der Antworten berechnen wir die Liste der Fragen. Beispiel
f0 ( xs : rest ) = ( "getArgs"               ) : f1 rest
f1 ( h  : rest ) = ( "hOpenFile " ++ head xs ) : f2 rest
f2 ..
Das System führt dann im Prinzip folgendes Programm aus
let aufgabe = f0 antworten
in  führe aufgaben der Reihe nach aus
Beide Listen sind (potentiell) unendlich lang, das stört aber nicht, da wir lazy evaluation haben. Was hingegen stört, wäre
f0 ( x : rest ) = if x == 5 then ( ... ) else ( ... )
das wird nicht gut gehen, denn die erste Antwort wird hier schon erwartet, bevor überhaupt eine Frage gestellt wurde.

Auf dieser expliziten Ebene fand tatsächlich in frühen Haskell-Versionen die Ein/Ausgabe statt. Das war natürlich erstens umständlich zu schreiben, und zweitens fehleranfällig (siehe voriges Beispiel).

Heutzutage steckt dieses Stream-Modell immer noch im Hintergrund (das geht auch gar nicht anders), aber wir haben

data IO a = IO ( [Antwort] -> ( a, [Frage] ) )
und exportieren nicht die beiden Streams, sondern nur solche Werte IO a, die sinnvollen Operationen mit den Streams entsprechen.

Nun könnte uns die Haskell-Implementierungs-Geschichte egal sein, aber wir benutzen die gleiche Idee im MIDI-Sequencer (nächste Woche).


best viewed with any browser


http://www.informatik.uni-leipzig.de/~joe/ mailto:joe@informatik.uni-leipzig.de