• Keine Ergebnisse gefunden

I. Funktionale Ein/Ausgabe

N/A
N/A
Protected

Academic year: 2022

Aktie "I. Funktionale Ein/Ausgabe"

Copied!
4
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Praktische Informatik 3: Funktionale Programmierung Vorlesung 10 vom 18.01.2021: Aktionen und Zustände

Christoph Lüth

Wintersemester 2020/21

11:51:34 2021-02-22 1 [32]

Fahrplan

ITeil I: Funktionale Programmierung im Kleinen ITeil II: Funktionale Programmierung im Großen

ITeil III: Funktionale Programmierung im richtigen Leben IAktionen und Zustände

IMonaden als Berechnungsmuster IFunktionale Webanwendungen IScala — Eine praktische Einführung IRückblick & Ausblick

PI3 WS 20/21 2 [32]

Inhalt

IEin/Ausgabe in funktionale Sprachen IWo ist dasProblem?

IAktionenund der DatentypIO.

IVordefinierteAktionen IBeispiel: Wortratespiel IAktionenalsWerte

PI3 WS 20/21 3 [32]

I. Funktionale Ein/Ausgabe

PI3 WS 20/21 4 [32]

Ein- und Ausgabe in funktionalen Sprachen

Umwelt Haskell

Umwelt Haskell

Aktionen Reine

Funktionen

Haskell

Problem:

IFunktionen mit Seiteneffekten nicht referentiell transparent.

IreadString ::...→String??

Lösung:

ISeiteneffekte am Typ erkennbar IAktionen

IKönnennurmitAktionenkomponiert werden I„einmal Aktion, immer Aktion“

PI3 WS 20/21 5 [32]

Aktionen als abstrakter Datentyp

IADT mit OperationenKompositionundLifting

ISignatur:

typeIOα

(=) :: IOα→(α→IOβ)→IOβ return :: α→IOα

IDazuelementareAktionen (lesen, schreiben etc)

PI3 WS 20/21 6 [32]

Elementare Aktionen

IZeile von Standardeingabe (stdin)lesen:

getLine :: IO String

IZeichenkette auf Standardausgabe (stdout)ausgeben:

putStr :: String→IO ()

IZeichenkette mit Zeilenvorschubausgeben:

putStrLn :: String→IO ()

PI3 WS 20/21 7 [32]

Einfache Beispiele

IEchoeinfach echo1 :: IO ()

echo1=getLine=putStrLn IEchomehrfach

echo :: IO ()

echo=getLine=putStrLn=λ_ →echo IWas passiert hier?

IVerknüpfenvon Aktionen mit= IJede Aktion gibtWertzurück

PI3 WS 20/21 8 [32]

(2)

Noch ein Beispiel

IUmgekehrtes Echo:

ohce :: IO ()

ohce=getLine=λs→putStrLn (reverse s)ohce IWas passiert hier?

IReineFunktionreversewird innerhalb vonAktionputStrLngenutzt IFolgeaktionohcebenötigtWertder vorherigen Aktion nicht IAbkürzung:

pq=p=λ_→ q

PI3 WS 20/21 9 [32]

Die do-Notation

ISyntaktischer Zucker fürIO:

echo= getLine

=λs→putStrLn s echo

⇐⇒

echo= dos←getLine

putStrLn s echo IRechts sind=,implizit

IMit←gebundene Bezeichnerüberlagernvorherige IEs gilt dieAbseitsregel.

IEinrückungderersten Anweisungnachdobestimmt Abseits.

PI3 WS 20/21 10 [32]

Drittes Beispiel

IZählendes, endliches Echo echo3 :: Int→IO () echo3 cnt=do

putStr (show cnt++":␣") s←getLine

ifs6="" then do

putStrLn $ show cnt++":␣"++s echo3 (cnt+ 1)

elsereturn () IWas passiert hier?

IKombinationausKontrollstrukturenundAktionen IAktionenalsWerte

IGeschachteltedo-Notation

PI3 WS 20/21 11 [32]

Zeit für eine Pause

Übung 10.1: Say My Name!

Wie sieht ein Haskell-Program aus, das erst nach dem Namen des Gegenübers fragt, und dann mitHallo, Christoph!(oder was eingegeben wurde) freundlich grüßt?

Lösung:

greeter :: IO () greeter=do

putStr "What’s␣your␣name,␣love?␣"

s ←getLine

putStrLn $ "Hullo,␣" ++s++".␣Pleased␣to␣meet␣you."

IputStrstattputStrLnerlaubt „Prompting“

IArgumente vonputStrLnklammern (oder$)

PI3 WS 20/21 12 [32]

II. Aktionen als Werte

PI3 WS 20/21 13 [32]

Aktionen als Werte

IAktionensindWertewie alle anderen.

IDadurchDefinitionvonKontrollstrukturenmöglich.

IEndlosschleife:

forever :: IOα→IOα forever a=aforever a IIteration (feste Anzahl):

forN :: Int→IOα→IO () forN n a | n==0 =return ()

| otherwise=aforN (n-1) a

PI3 WS 20/21 14 [32]

Kontrollstrukturen

IVordefinierteKontrollstrukturen (Control.Monad):

when :: Bool→IO ()→IO () ISequenzierung:

sequence :: [IOα]→IO [α]

ISonderfall:[()]als() sequence_ :: [IO ()]→IO ()

IMap und Filter für Aktionen:

mapM :: (α→IOβ)→[α]→ IO [β]

mapM_ :: (α→IO ())→[α]→IO () filterM :: (α→IO Bool)→[α]→IO [α]

PI3 WS 20/21 15 [32]

Jetzt ihr!

Übung 10.2: Eine „While-Schleife“ in Haskell Schreibt einen Kombinator

while :: IO Bool→IOα→IO ()

der solange das zweite Argument (den Rumpf) auswertet wie das erste Argument zuTrue auswertet.

Lösung:

IErste Lösung:

while c b=doa←c;ifa thenbwhile c belsereturn () IVorteil: istendrekursiv.

IWieso eigentlichIO ()?

PI3 WS 20/21 16 [32]

(3)

III. Ein/Ausgabe

PI3 WS 20/21 17 [32]

Ein/Ausgabe mit Dateien

IImPreludevordefiniert:

IDateien schreiben (überschreiben, anhängen):

typeFilePath= String

writeFile :: FilePath→String→IO () appendFile :: FilePath→String→IO () IDatei lesen (verzögert):

readFile :: FilePath→IO String I“Lazy I/O”: Zugriff auf Dateien erfolgtverzögert

IInteraktion von nicht-strikter Auswertung mit zustandsbasiertem Dateisystem kann überraschend sein

PI3 WS 20/21 18 [32]

Beispiel: Zeichen, Wörter, Zeilen zählen (wc)

wc :: String→IO () wc file=

docont ←readFile file putStrLn $ file++":␣"++

show (length (lines cont))++"␣lines,␣" ++ show (length (words cont))++"␣words,␣"++ show (length cont)++"␣bytes."

IDatei wird gelesen

IAnzahl Zeichen, Worte, Zeilen gezählt IErstaunlich (hinreichend) effizient

PI3 WS 20/21 19 [32]

Ein/Ausgabe mit Dateien: Abstraktionsebenen

IEinfach:readFile,writeFile

IFortgeschritten: ModulSystem.IOder Standardbücherei IBuffered/Unbuffered, Seeking, &c.

IOperationen aufHandle

ISystemnah:ModulSystem.Posix IFiledeskriptoren, Permissions, special devices, etc.

PI3 WS 20/21 20 [32]

IV. Ausnahmen und Fehlerbehandlung

PI3 WS 20/21 21 [32]

Fehlerbehandlung

IFehlerwerden durchExceptionrepräsentiert (ModulControl.Exception) IExceptionistTypklasse— kann durch eigene Instanzen erweitert werden IVordefinierte Instanzen: u.a.IOError

IFehlerbehandlungdurchAusnahmen(ähnlich Java) throw :: Exceptionγ⇒γ→α

catch :: Exceptionγ⇒IOα→(γ→IOα)→ IOα try :: Exceptionγ⇒IOα→IO (Eitherγ α) IFaustregel:catchfür unerwartete Ausnahmen,tryfür erwartete IAusnahmen überall, Fehlerbehandlungnur in Aktionen

PI3 WS 20/21 22 [32]

Fehler fangen und behandeln

“Ask forgiveness not permission” (Grace Hopper)

Generelle Regel:FehlerbehandlungdurchAusnahmebehandlungbesser als vorherige Abfrage von Fehlerbedingungen.

IWarum? Umwelt nichtsequentiell.

IFehlerbehandlung fürwc:

wc2 :: String→IO () wc2 file=

catch (wc file)

(λe →putStrLn $ "Fehler:␣"++show (e :: IOError)) IIOErrorkann analysiert werden (sieheSystem.IO.Error)

Ireadmit Ausnahme bei Fehler (statt Programmabbruch):

readIO :: Readα⇒String→IOα

PI3 WS 20/21 23 [32]

Ausführbare Programme

IEigenständiges Programm istAktion IHauptaktion:main :: IO ()in ModulMain

I. . . oder mit der Option-main-isM.fsetzen Iwcals eigenständiges Programm:

moduleMainwhere

importSystem.Environment (getArgs) importControl.Exception

main :: IO () main=do

args ←getArgs

putStrLn $ "Command␣line␣arguments:␣"++show args mapM_ wc2 args

PI3 WS 20/21 24 [32]

(4)

Beispiel: Traversion eines Verzeichnisbaums

IVerzeichnisbaum traversieren, und für jede Datei eineAktionausführen:

travFS :: (FilePath→IO ())→FilePath→IO () travFS action p=catch (do

cs←getDirectoryContents p

let cp=map (p</>) (cs \\ [".", ".."]) dirs ←filterM doesDirectoryExist cp files←filterM doesFileExist cp mapM_ action files

mapM_ (travFS action) dirs)

(λe →putStrLn $ "ERROR:␣"++show (e :: IOError)) INutzt Funktionalität ausSystem.Directory,System.FilePath

PI3 WS 20/21 25 [32]

Alles zählt.

Übung 10.3: Alles zählt

KombiniertTraverseundWCzu einem Programm ls :: FilePath→IO ()

welches in einem gegeben Verzeichnis den Inhalt aller darin enthaltenen Dateien zählt.

Lösung:wc2(mit Fehlerbehandlung) wird einfach die Traversionsfunktion:

ls=travFS wc2 Das ist alles.

PI3 WS 20/21 26 [32]

V. Anwendungsbeispiel

PI3 WS 20/21 27 [32]

So ein Zufall!

IZufallswerte:

randomRIO :: (α,α)→IOα IWarum istrandomIOAktion?

IBeispiele:

IAktion zufällig oft ausführen:

atmost :: Int→IOα→IO [α]

atmost most a=

dol←randomRIO (1, most) sequence (replicate l a) IZufälligen String erzeugen:

randomStr :: IO String

randomStr=atmost 40 (randomRIO (’a’,’z’))

IHinweis: Funktionen ausSystem.Randomzu importieren, muss ggf. installiert werden.

PI3 WS 20/21 28 [32]

Fallbeispiel: Wörter raten

IUnterhaltungsprogramm: der Benutzer rät Wörter

IBenutzer kann einzelne Buchstaben eingeben

IWort wird maskiert ausgegeben, nur geratene Buchstaben angezeigt

PI3 WS 20/21 29 [32]

Wörter raten: Programmstruktur

IHauptschleife:

play :: String→String→String→ IO ()

IArgumente: Geheimnis, geratene Buchstaben (enthalten, nicht enthalten) IBenutzereingabe:

getGuess :: String→String→IO Char

IArgumente: geratene Zeichen (im Geheimnis enthalten, nicht enthalten) IHauptfunktion:

main :: IO ()

ILiest ein Lexikon, wählt Geheimnis aus, ruft Hauptschleife auf

PI3 WS 20/21 30 [32]

Nunc est ludendum.

Übung 10.3: Linguistic Interlude

Ladet den Quellcode herunter, übersetzt das Spiel und ratet fünf Wörter.

Wer noch etwas tun möchte, kann das Spiel so erweitern, dass es nachdem das Wort erfolgreich geraten wurde, ein neues Wort rät, und insgesamt zählt, wieviele Worte schon (nicht) geraten wurden.

PI3 WS 20/21 31 [32]

Zusammenfassung

IEin/Ausgabe in Haskell durchAktionen

IAktionen(TypIO α) sind seiteneffektbehaftete Funktionen IKompositionvon Aktionen durch

(=) :: IOα→(α→IOβ)→IOβ return :: α→IOα

Ido-Notation

IFehlerbehandlung durch Ausnahmen (IOError,catch,try).

IVerschiedene Funktionen der Standardbücherei:

IPrelude:getLine,putStr,putStrLn,readFile,writeFile IModule:System.IO,System.Random

INächste Vorlesung: Wie sind Aktionen eigentlichimplementiert? Schwarze Magie?

PI3 WS 20/21 32 [32]

Referenzen

ÄHNLICHE DOKUMENTE

[r]

readMVar :: MVar α→ IO α −− MVar bleibt gefüllt takeMVar :: MVar α→ IO α −− MVar danach leer putMVar :: MVar α→ α → IO () −− Füllt MVar I readMvar und

Das heißt, das Magnetfeld hat keinen Effekt auf die Zustandssum- me und damit auf alle thermodynamischen Gr¨oßen wie z.B.. und nennen diese dann wieder m , um die beiden Summen

 Nebenwinkel haben einen gemeinsamen Schenkel, die beiden anderen Schenkel bilden eine Gerade.. Nebenwinkel ergänzen sich

[r]

/ŶĞŝŶĞƌƉƌŽƐƉĞŬƚŝǀĞŶ^ƚƵĚŝĞǁƵƌĚĞƵŶƚĞƌƐƵĐŚƚ͕ŽďĚŝĞɲͲ'ůƵĐŽƐŝĚĂƐĞͲŬƚŝǀŝƚćƚŝŵƵƐĂŵŵĞŶŚĂŶŐŵŝƚ ĚĞƌ ĨƵŶŬƚŝŽŶĞůůĞŶ ^ƉĞƌŵŝĞŶƋƵĂůŝƚćƚ njƵŵ ĞŝŶĞŶ

Zeichne eine geeignete Hilfslinie ein und bestätige damit weitere Angaben aus

Obieff/V/' Tutta una serie di incontri e di colloqui con la popolazione delle zone costiere del Bangladesh hanno indotto la CRS a formulare gli obiettivi per un aiuto a lungo