lassen sich nur schwer dem Grundprinzip "`Funktionsauswertung"' unterordnen.
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?
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 (
später), so sollte man
sich um eine show-Funktion kümmern.
> 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 (
Vorsicht bei
gebrauch von Literatur)
(Bemerkung: backslash
dient als Fluchtsymbol, andere
Verwendung:
'
![]() |
$=$ | backslash |
'
![]() |
$=$ | single quote |
'
![]() |
$=$ | 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
n nicht!
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.
putStr liefert als Ergebnis (Wert) eine Aktion, d.h. IO() und verwandte Typen beinhalten Aktionen, und Wiedergabe von sowas durch Hugs ist gleich Ausführung der Aktion.
(d.h. man kann anders als in Ada nicht während der Auswertung einer Funktion wie fac :: Int->Int mal ´was ausdrucken!)
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: