Senst Idg Högre ordningens funktioner Lismfttning Strikthet och lt evluering Strömmr I/O i Hskell Strikt evluering Icke-strikt evluering Def: Strikt evluering innebär tt ll prmetrrs värde är känd när en operr eller funktion nrops. Ex: Funktionsnrop i Jv, C, etc Hur beräkns if jobbigt(7) && tungt(47) then? Vnligen: Mn kortsluter jämförelsen. Implementers för nd och or Vd händer här? int min(int rgc, chr** rgv) { if (hej() hopp()) { printf("du glde\n"); else { printf("nix pix!\n"); int hej() { printf("hej "); return ; Lt evluering Hur beräkns hed [..0]? hed (qsort longlist)? Lt evluering i Hskell: Beräkn br det som behövs Vrje uttrck lgrs som ett löfte om evluering vid behov. int hopp() { printf("hopp "); return ; Test ltheten! Test ltheten! Vd händer med hed (qsort [4,5,4,,2,9])? Instrumenter koden: qsort [] = [] qsort (x : xs) = qsort [(observe e e) e<-xs, e<x] ++ [(observe x x)] ++ qsort [(observe e2 e) e<-xs, e>=x] Hugs> hed (qsort [4, 5, 4, 3,, 2,9]) >>>>>>> Observtions <<<<<< e 3 2 2 x Hugs> Ing värden på e2 det uttrcket hr ldrig behövt evluers
Plus och minus med lt evluering Vlfri strikthet Nckdelr: Fördelr: Kn slö ner ett progrm (nvänd då explicit strikt evluering!) Kn slös på minne: löftet tr plts Överrsknde för den ovetnde? Kn snbb upp ett progrm Undviker onödig beräkningr. Aumtiskt! Erbjuder smrt uttrckssätt. Operrn ($!). Ersätt f x med f $! x tvingr x tt evluers först. Funktionen seq :: -> b -> b let x = fkn = fkn2 in seq fkn3 x Anpssde funktioner, exv foldl. Strikt dttper, exv dt StrictColor = SRGB!r!g!b lgrr ing löften Strömmr: nvänd lt evluering Vd händer med ones = ( : ones)? Hugs> ones [ tke 0 ones? Hugs> tke 0 ones [,,,,,,,,,] ex = ( : mp ((+) ) ex)? Hugs> tke 0 ex [,2,3,4,5,6,7,8,9,0] Inbggt i Hskell: [..] == ex Mer exempel ex2 = conct (mp (\x -> [x,-x]) ex) Hugs> tke 0 ex2 [,-,2,-2,3,-3,4,-4,5,-5] Hur t frm ll tl-pr? llpirs = [(x, ) x <- [..], <- [x, (x-)..]] Hugs> tke 0 llpirs [(,),(2,2),(2,),(3,3),(3,2),(3,), (4,4),(4,3),(4,2),(4,)] Strömmr: Oändlig lisr Tpexemplet: Fibonccitlen Antg tt fibs är listn v Fibonccitl. 2 3 5 8 3 2 fibs + 2 3 5 8 3 2 34 til fibs 2 3 5 8 3 2 34 55 til(til fibs) fibs = ::(elementwiseadd fibs (til fibs)) where elementwiseadd = zipwith (+) Hugs> tke 0 fibs [,,2,3,5,8,3,2,34,55] Pseudoslumptl i Hskell Ett sätt tt generer pseudoslumptl: Ström v pseudoslumptl: Måste skicks med överllt. module MinSimulr where import Rndom prng :: Int -> Int -> [Int] prng n seed = rndomrs (0,n-) (mkstdgen seed) Hugs> :lod MinSimulr Hugs> tke 0 (prng 00 47) [37,92,38,24,22,60,2,24,38,6] Hugs> runsimultion strt (prng 00 47) Strömmr i Unix Strömmr och pipes i Unix Antg du snbbt måste rder mång filer: $ rm -r MinHemligMP3 rm: remove write-protected file finl_countdown.mp3? rm: remove write-protected file BestOf80s.zip? rm: remove write-protected file trckslistn85.zip? Två tips:. Använd rm -rf! 2. eller nvänd es $ es rm -r MinHemligMP3 stdin, stdout, stderr är lltid (?) definierde och öppn. God vn tt lltid läs från stdin skriv till stdout, och skriv felmeddelnden till stderr. Str om med < och > $ sort < infilen > utfilen Koppl ihop stdout och stdin med $ ct infilen sort > utfilen
$ es Vd gör es? tills mottgnde progrmmet vsluts och strömmen stängs. Minns: $ es rm -r MinHemligMP3 Lthet med hjälp v I/O-buffertr! Knuths lösning Elegnt progrmmering Elegnt specildesignd dtstruktur (prefixträd) Noggrnt kommentert och presentert Kritikern, Doug McIlro, AT&T Bell Lbs: Ver few people cn obtin the virtuoso services of Knuth [] ttck problems such s Bentle s from the ground up. But old Unix hnds knows instinctivel how solve this one in jiff. (McIlro uppfnn pipes i Unix.) Strömmr som prdigm Kräver nån sorts lthet Uttrcksfullt, snggt God ingenjörskonst! Läs från stdin Skriv till stdout Felmeddelnden till stderr Progrmming perls Klssisk rtikelserie i Communictions of the ACM, Jon Bentle. Idé: Låt en stjärn lös ett problem och låt en nnn stjärn kritiser lösningen. 986: Given text file nd n integer k, ou re print the k most common words in the file (nd the number of occurrences) in decresing frequenc. Donld Knuth fick uppdrget. McIlros lösning: strömmr i Unix $ ct MittLitterärVerk.txt tr -cs A-Z-z ˆj # Rdbrtningr tr A-Z -z # Versler blir gemen sort # Sorter orden uniq -c # Sml ihop och räkn sort -rn # Sorter efter ntl hed -n 0 # Vis de först 0 Looking bck ll tht hs occurred me since tht eventful d, I m scrcel ble believe in the relit of m dventures. The were trul so wonderful tht Looking bck ll tht looking bck ll tht Looking bck ll tht looking bck ll tht Problemet med I/O I/O ej funktionellt getchr plockr bort ett tecken från en 885 nån buffert 3 bndon putchr skriver in ett tecken 4 bndoned i en buffert. bndoning Hur åstdkomm I/O utn sideffekter? bbeville 885 Lisp mfl: Fusk! Använd 5834 sidoeffekter. the 3 bndon 3634 of 4 bndoned 2579 bndoning 2323 nd bbeville 2098 i I/O i Hskell Pseudokod: min = printstr("rev: ") printstr(reverse(getline)) I impertivt progrm: Ordning och direkt tillgång till omvärlden. I Hskell: Ordning oklr, ll funktioner hr värden, tillåter ej sidoeffekter.. Lt I/O: Låtss läs in llt i börjn. 2. Mondisk I/O: Kpsl in världen på ett säkert sätt Speciell nottion för I/O.
interct: en god Unix-medborgre interct: en god Unix-medborgre interct :: (String -> String) -> IO () import Dt.Chr min = interct (mp Upper) Läs från stdin Skriv till stdout Vd gör dett? module Min where import Dt.List min = interct (conct. sort. lines) interct: en god Unix-medborgre De 0 vnligste orden Vd gör dett? module Min where import Dt.List newline str = str ++ "\n" min = interct (newline. show. length. words) module Min where import Dt.List (sortb, sort, group) import Dt.Chr (Lower) countelems = mp (\x -> (hed x, length x)) sortbsnd = sortb (\x -> snd compre snd x) lower = mp Lower rnkwords = sortbsnd. countelems. group. sort. words. lower formtoutput = unlines. mp (\(str, i) -> str ++ "\t" ++ show i) min = interct (formtoutput. (tke 0). rnkwords) Mondisk I/O Designprincip för I/O i Hskell Särskild nottion som döljer problemen Monder: funktionellt idiom för sekvensiell beroenden tt dölj prmetrr förenkl kod Världen Mondisk IO Din kod Filer getchr mpreprtions Portr getline computeitall stdin/stdout openfile mfilter Grfik redfile iseof m.m. Ansts: Kpsl in världen Till versler igen Vd vi vill h: tpe IO = World -> (, World) IO-tper är hndlingr: Eng: ctions Exempel: getchr :: IO Chr getchr :: World -> (Chr, World) putchr :: Chr -> IO () putchr :: Chr -> World -> ((), World) iseof getline :: IO Bool :: IO String Låtss läs hel filen: module Min where import Dt.Chr min = do { str <- getcontents; putstrln (mp Upper str);
Räkn ord igen Lt I/O: räkn ord i fil module Min where min =do { input <- getcontents; ws <- return (length (words input)); putstrln (show ws); module Min where min = do { ih <- openfile "input.txt" RedMode; ws <- return (length (words input)); putstrln(show ws); hclose(ih) Två n operrer i mondisk I/O <- plockr ut ett värde från IO-monden. Kn skicks till ren funktioner utn IO-signtur. return betder sätt in ett värde i IO-monden. return A skpr värde v tpen IO Chr. Viktigt: return vslutr ej ett do-uttrck! Lt I/O: räkn ord i given fil Förenkl koden min = do { ih <- openfile "input.txt" RedMode; ws <- return (length (words input)); putstrln(show ws); hclose(ih) blir min = do { rgs <- getargs; ih <- openfile (hed rgs) RedMode; putstrln (show (length (words input))); hclose(ih); Lt I/O frligt, vrför? module Min where import Sstem.Environment (getargs) min = do { rgs <- getargs; ih <- openfile (hed rgs) RedMode; putstrln(show (length (words input))); hclose(ih); min = do { ih <- openfile "input.txt" RedMode; hclose(ih); putstrln(show (length (words input))); Egen kod i IO-monden: getline Exempel: Räkn rder och tecken getline :: IO [Chr] getline = do { c <- getchr; if c == \n then return [] else do { cs <- getline; return (c : cs) Pketer resulttet med return Indt: Läs från stdin Utdt: Skriv ntlet rder och tecken till stdout module Min where min = do {(nlines, nchrs) <- wc 0 0; putstrln (show nlines ++ "\t" ++ show nchrs)
Exempel: Räkn tecken och rder wc :: Int -> Int -> IO (Int, Int) wc nlines nchrs= do flg <- iseof if flg then return (nlines, nchrs) else consumeandcount nlines nchrs consumeandcount :: Int -> Int -> IO (Int, Int) consumeandcount nl nc = do { c <- getchr; if (c == \n ) then wc ( + nl) ( + nc) else wc nl (+nc) Lur Hskell med unsfeperformio Hugs> wc 0 0 hubb ^D Hugs> min hubb ^D 6 Hugs> I terminlen: $ runhugs wc.hs hubb bubb ^D 2 2 $ Test progrmmet Näst gång Ett trick för tt komm runt mondreglern: unsfeperformio :: IO -> Använd inte för F4 eller på tent Pen-Jones: Riktigt obekväm I/O, Once-per-run I/O Debugging: trce :: String -> -> trce s x = unsfeperformio (putstrlns s >> return x) men vi hr ju Hugs.Observe! Mer om monder Korrekthet i progrm