Lazy I/O in Haskell Funktionale Programmierung Haskell: Lazy IO D. Rösner Institut für Wissens- und Sprachverarbeitung Fakultät für Informatik Otto-von-Guericke Universität Magdeburg c Sommer 2014, 18. Juni 2014, 2011-14 D.Rösner D. Rösner FP 2014 . . . Lazy I/O in Haskell Gliederung 1 Lazy I/O in Haskell hGetContents readFile und writeFile interact D. Rösner FP 2014 . . . Lazy I/O in Haskell hGetContents readFile und writeFile interact Lazy I/O in Haskell: Haskell ist ’lazy’ Daten werden nur ausgewertet, wenn der Wert tatsächlich benötigt wird das gilt auch für I/O Beispiel: Funktion hGetContents Typ: hGetContents :: Handle -> IO String relevante Literatur: s. u.a. [OGS09], Ch. 7, [Tho11], [Tho99], Ch. 18 D. Rösner FP 2014 . . . Lazy I/O in Haskell hGetContents readFile und writeFile interact Lazy I/O in Haskell: cont. hGetContents :: Handle -> IO String der von hGetContents zurückgegebene String wird ’lazy’ berechnet beim Aufruf von hGetContents wird zunächst garnichts gelesen erst dann wird vom Handle gelesen, wenn Elemente der Liste (also: Zeichen) verarbeitet werden ... [OGS09], Ch. 7 D. Rösner FP 2014 . . . Lazy I/O in Haskell hGetContents readFile und writeFile interact Lazy I/O in Haskell: cont. hGetContents :: Handle -> IO String ... sofort, wenn Elemente nicht mehr benötigt werden, gibt der Garbage collector von Haskell den zugehörigen Speicher frei der Benutzer muß sich nicht darum kümmern für ihn geschieht alles völlig transparent es steht der Inhalt der Datei als reiner String zur Verfügung, der mit reinem Code verarbeitet werden kann [OGS09], Ch. 7 D. Rösner FP 2014 . . . Lazy I/O in Haskell hGetContents readFile und writeFile interact Lazy I/O in Haskell: cont. -- file: ch07/toupper-lazy1.hs import System.IO import Data.Char(toUpper) main :: IO () main = do inh <- openFile "input.txt" ReadMode outh <- openFile "output.txt" WriteMode inpStr <- hGetContents inh let result = processData inpStr hPutStr outh result hClose inh hClose outh processData :: String -> String processData = map toUpper [OGS09], Ch. 7 D. Rösner FP 2014 . . . Lazy I/O in Haskell hGetContents readFile und writeFile interact Lazy I/O in Haskell: cont. -- file: ch07/toupper-lazy2.hs import System.IO import Data.Char(toUpper) main = do inh <- openFile "input.txt" ReadMode outh <- openFile "output.txt" WriteMode inpStr <- hGetContents inh hPutStr outh (map toUpper inpStr) hClose inh hClose outh [OGS09], Ch. 7 D. Rösner FP 2014 . . . Lazy I/O in Haskell hGetContents readFile und writeFile interact Lazy I/O in Haskell: cont. da sehr oft Dateien gelesen, ihr Inhalt verarbeitet und das Ergebnis wieder in eine Datei geschrieben wird, gibt es mit readFile und writeFile zwei Funktionen zum komfortablen Arbeiten mit Dateien als Strings die Typen: ghci> :type readFile readFile :: FilePath -> IO String ghci> :type writeFile writeFile :: FilePath -> String -> IO () [OGS09], Ch. 7 D. Rösner FP 2014 . . . Lazy I/O in Haskell hGetContents readFile und writeFile interact Lazy I/O in Haskell: cont. -- file: ch07/toupper-lazy3.hs import Data.Char(toUpper) main = do inpStr <- readFile "input.txt" writeFile "output.txt" (map toUpper inpStr) readFile verwendet hGetContents intern [OGS09], Ch. 7 D. Rösner FP 2014 . . . Lazy I/O in Haskell hGetContents readFile und writeFile interact Lazy I/O in Haskell: cont. für die gängige Situation des Lesens von Standard-Input, Konvertierens der Eingabe und Ausgabe auf Standard-Output: interact :: (String -> String) -> IO () -- file: ch07/toupper-lazy4.hs import Data.Char(toUpper) main = interact (map toUpper) [OGS09], Ch. 7 D. Rösner FP 2014 . . . Lazy I/O in Haskell hGetContents readFile und writeFile interact Lazy I/O in Haskell: cont. einfache interaktive Programme mit interact -- file: ch07/toupper-lazy6.hs import Data.Char(toUpper) main = interact ((++) "Your data, in uppercase, is:\n\n" . map toUpper) [OGS09], Ch. 7 D. Rösner FP 2014 . . . Lazy I/O in Haskell hGetContents readFile und writeFile interact Lazy I/O in Haskell: cont. Beispiel: Filtern mit interact -- file: ch07/filter.hs main = interact (unlines . filter (elem ’a’) . lines) Hilfsfunktionen: lines :: String -> [String] unlines :: [String] -> String [OGS09], Ch. 7 D. Rösner FP 2014 . . . Lazy I/O in Haskell hGetContents readFile und writeFile interact Lazy I/O in Haskell: cont. Beispiel: Umdrehen der Zeilen der Eingabe bei interact -- file: ch07/reverseLines.hs main = interact (unlines . map reverse . lines) mögliche Nutzung: H:\Daten\work\haskell\code\realWorldHaskell\ch07>runghc reverseLines.hs nur du gudrun nurdug ud run eine treue familie bei lima feuerte nie ein etreuef amil ieb eilimaf euert enie ^Z H:\Daten\work\haskell\code\realWorldHaskell\ch07> D. Rösner FP 2014 . . . Lazy I/O in Haskell hGetContents readFile und writeFile interact Literatur: I Bryan O’Sullivan, John Goerzen, and Don Stewart. Real World Haskell. O’Reilly Media, Sebastopol, CA 95472, 2009. ISBN 978-0-596-51498-3; online available at http://book.realworldhaskell.org/. Simon Thompson. Haskell - The Craft of Functional Programming. Addison Wesley Longman Ltd., Essex, 1999. 2nd edition, ISBN 0-201-34275-8; Accompanying Web site: http://www.cs.ukc.ac.uk/people/staff/sjt/craft2e. D. Rösner FP 2014 . . . Lazy I/O in Haskell hGetContents readFile und writeFile interact Literatur: II Simon Thompson. Haskell - the craft of functional programming. Pearson Education Ltd., Essex, 2011. 3rd edition, ISBN 978-0-201-88295-7; Accompanying Web site: http://www.haskellcraft.com. D. Rösner FP 2014 . . .