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: import Hugs.Observe -- Ej stndrdmodul qsort [] = [] qsort (x : xs) = qsort [(observe e e) e<-xs, e<x] ++ [(observe x x)] ++ qsort [(observe e2 e) e<-xs, e>=x] QS> hed (qsort [4, 5, 4, 3,, 2,9]) >>>>>>> Observtions <<<<<< e 3 2 2 x QS> 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 { ih <- openfile "input.txt" 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 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: vis :: String -> -> vis s x = unsfeperformio (putstrlns s >> return x) Test progrmmet WC> wc 0 0 hubb ^D WC> min hubb ^D 6 WC> I terminlen: $ ghc -o minwc minwc.hs $./minwc hubb bubb ^D 2 2 $ Hskell i verkligheten Dt.BteString för strängr: bte/bokstv istället för c 2 bte/bokstv Dt.Mp för ssocitiv lisr Opertioner är O(log n). Dt.Arr, en oföränderlig rr Vnlig (?) Arr som mond: Dt.Arr.ST Mps give us the sme cpbilities s hsh tbles do in other lnguges. Internll, mp is implemented s blnced binr tree. Compred hsh tble, this is much more efficient representtion in lnguge with immutble dt. This is the most visible exmple of how deepl pure functionl progrmming ffects how we write code: we choose dt structures nd lgorithms tht we cn express clenl nd tht perform efficientl, but our choices for specific tsks re often different their counterprts in impertive lnguges Näst gång Sntxnls (KS Hskell 26/0) Från Rel World Hskell