Praktische Informatik 3
Einf¨uhrung in die Funktionale Programmierung
Vorlesung vom 07.01.09:
Ein/Ausgabe in Funktionalen Sprachen
Christoph L¨uth
WS 08/09
Christoph L¨uth: Praktische Informatik 3 1 WS 08/09
Fahrplan
Teil I: Grundlagen Teil II: Abstraktion
Abstrakte Datentypen Signaturen & Axiome Korrektheit von Programmen Zustand und Aktionen
Teil III: Beispiele, Anwendungen, Ausblicke
Christoph L¨uth: Praktische Informatik 3 1 WS 08/09
Inhalt
Ein/Ausgabe in funktionale Sprachen Wo ist dasProblem?
Aktionenund der DatentypIO.
Beispiel: Worte z¨ahlen (wc) AktionenalsWerte
Christoph L¨uth: Praktische Informatik 3 2 WS 08/09
Ein- und Ausgabe in funktionalen Sprachen
Problem:
Funktionen mit Seiteneffekten nicht referentiell transparent.
z. B.readString :: ... ->
String??
L¨osung:
Seiteneffekte am Typ erkennbar Aktionenk¨onnennurmitAktionen komponiert werden
”einmal Aktion, immer Aktion“
Aktionen
Umwelt Reine
Funktionen Haskell
Christoph L¨uth: Praktische Informatik 3 3 WS 08/09
Modellierung des Systemzustands
Idee: Aktionen sindTransformationenauf Systemzustand Σ Operationen:
AdressenA, WerteV Lesen:read:A→Σ→V×Σ Schreiben:write:A→V→Σ→Σ,
Aquivalent, aber besser¨ write:A→V→Σ→()×Σ Eine Aktion istI→Σ→O×Σ ∼= I×Σ→O×Σ
EinheitlicheSignatur f¨uralleAktionen Parametrisiert ¨uber ErgebnistypO
Christoph L¨uth: Praktische Informatik 3 4 WS 08/09
Komposition von Aktionen
Komposition istFunktionskomposition
WennR¨uckgabewertder ersten AktionpEingabewertder zweitenq:
p:A→Σ→B×Σ q:B→Σ→C×Σ p;q:A→Σ→C×Σ (p;q)a S= let(b,S1) =p a S
in q b S1
Liftingˆa: Σ→A×Σ f¨ur jedesa:Adefiniert als ˆa(S) = (a,S)
Christoph L¨uth: Praktische Informatik 3 5 WS 08/09
Aktionen als abstrakter Datentyp
Idee:IOaist Σ→a×Σ
ADT mit OperationenKompositionundLifting Signatur:
type IO t
(>>=) :: IO a -> (a-> IO b) -> IO b return :: a-> IO a
PluselementareOperationen (lesen, schreiben etc)
Christoph L¨uth: Praktische Informatik 3 6 WS 08/09
Vordefinierte Aktionen
Zeile vonstdinlesen:
getLine :: IO String
Zeichenkette aufstdoutausgeben:
putStr :: String-> IO ()
Zeichenkette mit Zeilenvorschubausgeben:
putStrLn :: String-> IO ()
Christoph L¨uth: Praktische Informatik 3 7 WS 08/09
Einfache Beispiele
Echoeinfach echo1 :: IO ()
echo1 = getLine >>= putStrLn Echomehrfach
echo :: IO ()
echo = getLine >>= putStrLn >>= \_ -> echo Was passiert hier?
Verkn¨upfenvon Aktionen mit>>=
Jede Aktion gibtWertzur¨uck
Christoph L¨uth: Praktische Informatik 3 8 WS 08/09
Noch ein Beispiel
Umgekehrtes Echo:
ohce :: IO () ohce = getLine
>>= \s-> putStrLn (reverse s)
>> ohce Was passiert hier?
ReineFunktionreversewird innerhalb vonAktionputStrLngenutzt Folgeaktionohceben¨otigt Wert der vorherigen Aktion nicht Abk¨urzung:>>
p >> q = p >>= \_ -> q
Christoph L¨uth: Praktische Informatik 3 9 WS 08/09
Die do-Notation
Syntaktischer Zucker f¨urIO:
echo = getLine
>>= \s-> putStrLn s
>> echo
⇐⇒
echo =
do s<- getLine putStrLn s echo Rechts sind>>=,>>implizit.
Es gilt dieAbseitsregel.
Einr¨uckungderersten Anweisungnachdobestimmt Abseits.
Christoph L¨uth: Praktische Informatik 3 10 WS 08/09
Module in der Standardb¨ ucherei
Ein/Ausgabe, Fehlerbehandlung (ModulIO) Zufallszahlen (ModulRandom)
Kommandozeile, Umgebungsvariablen (ModulSystem) Zugriff auf das Dateisystem (ModulDirectory) Zeit (ModulTime)
Christoph L¨uth: Praktische Informatik 3 11 WS 08/09
Ein/Ausgabe mit Dateien
ImPreludevordefiniert:
Dateien schreiben (¨uberschreiben, anh¨angen):
type FilePath = String
writeFile :: FilePath -> String -> IO () appendFile :: FilePath -> String -> IO () Datei lesen (verz¨ogert):
readFile :: FilePath -> IO String Mehr Operationenim ModulIOder Standardb¨ucherei
Buffered/Unbuffered, Seeking, &c.
Operationen aufHandle
Christoph L¨uth: Praktische Informatik 3 12 WS 08/09
Beispiel: Zeichen, W¨ orter, Zeilen z¨ ahlen (wc)
wc :: String-> IO () wc file =
do c <- readFile file
putStrLn (show (length (lines c), length (words c), length c) ++
" lines, words, characters.") Nicht sehr effizient — Datei wirdim Speicher gehalten.
Christoph L¨uth: Praktische Informatik 3 13 WS 08/09
Beispiel: wc verbessert.
Effizienter: Funktioncnt, die Dateiinhalteinmaltraversiert
cnt :: Int-> Int-> Int-> Bool-> String-> (Int, Int, Int) cnt l w c _ [] = (l, w, c)
cnt l w c blank (x:xs)
| isSpace x && not blank = cnt l’ (w+1) (c+1) True xs
| isSpace x && blank = cnt l’ w (c+1) True xs
| otherwise = cnt l w (c+1) False xs where l’ = if x == ’\n’ then l+1 else l
Christoph L¨uth: Praktische Informatik 3 14 WS 08/09
Beispiel: wc verbessert.
Mitcntbessereswc:
wc’ :: String-> IO () wc’ file =
do c <- readFile file
putStrLn (show (cnt 0 0 0 False c)++
" lines, words, characters.")
Datei wirdverz¨ogert gelesenunddabei verbraucht.
Christoph L¨uth: Praktische Informatik 3 15 WS 08/09
Aktionen als Werte
AktionensindWertewie alle anderen.
DadurchDefinitionvonKontrollstrukturenm¨oglich.
Beispiele:
Endlosschleife:
forever :: IO a-> IO a forever a = a >> forever a Iteration (feste Anzahl):
forN :: Int-> IO a-> IO () forN n a | n == 0 = return ()
| otherwise = a >> forN (n-1) a
Christoph L¨uth: Praktische Informatik 3 16 WS 08/09
Fehlerbehandlung
Fehlerwerden durchIOErrorrepr¨asentiert
FehlerbehandlungdurchAusnahmen(¨ahnlich Java)
ioError :: IOError -> IO a -- "throw"
catch :: IO a-> (IOError-> IO a) -> IO a
Fehlerbehandlungnur in Aktionen
Christoph L¨uth: Praktische Informatik 3 17 WS 08/09
Fehler fangen und behandeln
Fehlerbehandlung f¨urwc:
wc2 :: String-> IO () wc2 file =
catch (wc’ file)
(\e-> putStrLn ("Fehler beim Lesen: "++ show e)) IOErrorkann analysiert werden (siehe ModulIO)
readmit Ausnahme bei Fehler (statt Programmabbruch):
readIO :: Read a=> String-> IO a
Christoph L¨uth: Praktische Informatik 3 18 WS 08/09
Map und Filter f¨ ur Aktionen
Map f¨ur Aktionen:
mapM :: (a-> IO b)-> [a]-> IO [b]
mapM_ :: (a-> IO ())-> [a]-> IO () Filter f¨ur Aktionen
Importieren mitimport Monad (filterM).
filterM :: (a -> IO Bool) -> [a] -> IO [a]
Christoph L¨uth: Praktische Informatik 3 19 WS 08/09
So ein Zufall!
Zufallswerte:
randomRIO :: (a, a)-> IO a WarumistrandomIOAktion?
Beispiel:Aktionen zuf¨allig oft ausf¨uhren atmost :: Int-> IO a-> IO [a]
atmost most a =
do l<- randomRIO (1, most) mapM id (replicate l a) Zuf¨alligen String erzeugen randomStr :: IO String
randomStr = atmost 40 (randomRIO (’a’,’z’))
Christoph L¨uth: Praktische Informatik 3 20 WS 08/09
Ausf¨ uhrbare Programme
Eigenst¨andiges Programm istAktionen Hauptaktion:mainin ModulMain wcals eigenst¨andiges Programm:
module Main where
import System.Environment (getArgs) main = do
args <- getArgs mapM wc2 args
Christoph L¨uth: Praktische Informatik 3 21 WS 08/09
Zusammenfassung
Ein/Ausgabe in Haskell durchAktionen
Aktionen(TypIO a) sind seiteneffektbehaftete Funktionen Komposition von Aktionen durch
(>>=) :: IO a-> (a-> IO b)-> IO b return :: a-> IO a
do-Notation
Fehlerbehandlung durch Ausnahmen (IOError,catch).
Verschiedene Funktionen der Standardb¨ucherei:
Prelude:getLine,putStr,putStrLn,readFile,writeFile Module:IO,Random
Christoph L¨uth: Praktische Informatik 3 22 WS 08/09