next up previous contents
Next: Listen Up: Grundlegende Sprachelemente Previous: Auswertung von Ausdrücken

Input / Output

lassen sich nur schwer dem Grundprinzip "`Funktionsauswertung"' unterordnen.

Beispiel:

Interaktion mit Benutzer durch Ausgabe von Ergebnissen und Aufforderung zu weiterer Eingabe.

Eine saubere Lösung benötigt erhebliche theoretische/konzeptuelle Vorbereitung; hier Beschränkung auf Rezept für Teilproblem:

Wie kriegt man Ergebnis einer Berechnung in sinnvoll formatierter Weise ausgedruckt?

1.
die üblichen Datentypen gehören zu einer Typklasse Show und bieten eine Funktion show::(Show a) => a -> String, die Wert (Element des Datentyps) in einen String umwandelt;

Diese Funktion wird von Hugs zur Ausgabe von Ergebnissen benutzt.

Es gibt Typen, die nicht zur Klasse Show gehören, insbesondere Funktionstypen.

Führt man selber neue Datentypen ein ( $\Rightarrow$ später), so sollte man sich um eine show-Funktion kümmern.

2.
Hugs benutzt show-Funktionen, gibt aber dann Antworten üblicherweise nicht in Form von Haskell-String-Bezeichnern, sondern eben die Zeichenreihe selbst:

 > fac 3

6

Ausnahme:

Werte vom Typ String werden so ausgegeben, wie sie auch in der Programmiersprache auftreten, nämlich in Anführungszeichen:

 > "ABC"

"ABC"

Differenz zu älteren Hugs-Versionen oder Gofer ( $\Rightarrow$ Vorsicht bei gebrauch von Literatur)

3.
zum Zeichenvorrat Char gehören neben druckbaren Zeichen auch Steuerzeichen, insbesondere newline Symbol: ' $\backslash$n'

(Bemerkung: backslash $\backslash$ dient als Fluchtsymbol, andere Verwendung:

' $\backslash\backslash$' $=$ backslash
' $\backslash$´' $=$ single quote
' $\backslash$ $=$ double quote )

Mann kann dan Text formatieren wie z.B.:

 "dies ist \neine neue Zeile "

was man mit Hilfe des Konkatenationsoperators ++ vielleicht sinnfälliger schreiben kann als

 "dies ist \n" ++ "eine neue Zeile"

Aber: wegen vorherigem Punkt hilft das noch nicht viel:

Hugs druckt gnadenlos den String:

 > "dies ist \n" ++ "eine neue Zeile"

"dies ist \neine neue Zeile"

d.h. interpretiert $\backslash$n nicht!

4.
Vernünftig wird das Resultat durch Vorschalten der Funktion

 putStr :: String -> IO()

nämlich:

 > putStr("dies ist \n" ++ "eine neue Zeile")

dies ist
eine neue Zeile

Sorry: Genaue Diskussion des "`Wertebereichs"' dieser "`Funktion"' ist hier nicht möglich.

Beispiel:

Wir machen die Fakultätsfunktion "`fehlertolerant"' dadurch, daß sie für negative Argumente eine entsprechende Meldung erzeugt.

Dazu: ändere Fakultätsfunktion so, daß sie Zeichenreihe als Ergebnis hat:

 fac:: Int->Int

fac 0 = 1
fac n = n*fac (n-1)


fault_tolerant_fac::Int->String
fault_tolerant_fac n
|n >= 0 = show(fac n)
|otherwise = ">>>: fac nicht definiert \n"++
" fuer "++ (show n)


Main> fault_tolerant_fac 3
"6"
Main> fault_tolerant_fac (-3)
">>>: fac nicht definiert \n fuer -3"
Main> putStr (fault_tolerant_fac (-3))
>>>: fac nicht definiert
fuer -3

Für dieses Beispiel gibt es eine bessere Lösung: Haskell hat Vorkehrungen für Ausnahmebehandlung, z.B.:

 error :: String->a

Dies ist auch wieder eine Funktion, die auf eine Aktion hinausläuft: Abbruch der Auswertung, aber: vorher wird die als Argument gegebene Zeichenreihe ausgedruckt.

(error hat den polymorphen Ergebnistyp a, damit man die Funktion in jeden Zusammenhang einfügen kann)

 fault_tolerant_fac::Int->Int

fault_tolerant_fac n
|n >= 0 = fac n
|otherwise = error (" fac nicht definiert fuer " ++ (show n))


Main> fault_tolerant_fac (-3)


Program error: fac nicht definiert fuer -3

Wirkung von error:

1.
Abbruch (= Program error)
2.
Ausgabe des vom Programmierer vorgesehenen String


next up previous contents
Next: Listen Up: Grundlegende Sprachelemente Previous: Auswertung von Ausdrücken
Ronald Blaschke
1998-04-19