Introduktion till programmering Standardfunktioner Tecken och strängar Utskrifter och effekter Föreläsning 2 Prelude Alla fördefinierade funktioner vi använder definieras i modulen Prelude. Denna modul importeras automatiskt i Haskell-program. Om man startar ghci utan att ange något filnamn är det modulen Prelude som laddas: $ ghci... Prelude> Innehållet i Prelude hittar ni här: http://hackage.haskell.org/packages/archive/base/latest/doc/html/prelude.html Standardfunktioner Vad används datorer till? Hoogle För att hitta information om standardfunktioner kan man använda sökmotorn Hoogle: http://www.haskell.org/hoogle/ Testa att söka på "take" samt på typen "Int -> [a] -> [a]" 1. Numeriska beräkningar I går använde vi ghci för att göra enkla beräkningar med tal (och listor av tal). Många viktiga datortillämpningar bygger på avancerade matematiska beräkningar med tal: Mobil kommunikation Hållfasthetsberäkningar för nya konstruktioner Väderprognoser Kryptering av kommunikation I den här kursen kan vi inte ens närma oss dessa tillämpningar.
Vad används datorer till? 2. Bearbetning av text Många andra tillämpningar handlar i stället om avancerad textbehandling: Ordbehandling och typsättning (Word etc). Sökmotorer (Google etc). Maskinell översättning mellan olika språk. I dag ska vi titta på enkel texthantering i Haskell. 3. Mycket annat Som inbyggd komponent i bilar, flygplan, telefoner, För att spela musik, visa film, spela spel, För att hantera stora databaser. Tecken och strängar i Haskell Typen Char Typen Char innehåller som värden tecken, vilka skrivs som i dessa exempel: 'a' 'B' '7' '?' För vissa speciella tecken finns särskild notation: '\n' för ny rad. Strängar I preluden definieras type String = [Char] så till exempel har listan ['k','o','r','k'] typen String. Men för strängar finns också en speciell notation. Vi kan bekvämare skriva denna lista som "kork". Funktioner med strängar En ny operator: konkatenering Strängar är listor, så vi kan göra så här Prelude> length "kork" 4 Prelude> [ c c <- "kork", c /= 'k'] "or" Prelude> take 2 "kork" "ko" Prelude> ['a'.. 'z'] "abcdefghijklmnopqrstuvwxyz" Prelude> ['a','a'..] "aaaaaaaaaaaaaaaaaaaaaainterrupted Interaktion med ghci Prelude> "kork" ++ "skruv" "korkskruv" Prelude> [1..5] ++ [3,8] [1,2,3,4,5,3,8] Prelude> "hej" ++ " " ++ "du" "hej du" Prelude> Operatorn ++ definieras i preluden, men med metoder som vi väntar med till nästa kurs. Men använda ++ kan vi göra!
Ytterligare två exempel Två till funktioner ur preluden rmspaces Definera en funktion rmspaces :: String -> String så att rmspaces str är samma som str men med alla blanktecken borttagna. count Definiera en funktion count :: Char -> String -> Int words Prelude> words "till och med" ["till", "och", "med"] Vilken typ har resultatet? unwords Prelude> unwords ["till", "och", "med"] "till och med" så att count c str är antalet förekomster av c i str. Översättning ord för ord Mönstermatchning En allmän idé Ersätt varje ord i en sträng med ett annat: Svenska ord med norska ord (maskinöversättning) Fula ord med anständiga ord (censur) Varje ord med sin första bokstav (förkortning) Var och en av dessa kan åstadkommas av translate str = unwords [replace w w <- words str] för en lämplig definition av replace. Övning Hur ska replace definieras för det sista exemplet ovan? Svenska till norska Vi kan definiera en ersättningsfunktion på följande sätt: replace "inte" = "ikke" replace "jag" = "jeg" replace w = w Exempel på översättning Prelude> translate "jag kommer inte med" "jeg kommer ikke med" Trots exemplet är översättning ord för ord otillräcklig för maskinöversättning.
Reversering Preludfunktionen reverse Prelude> reverse "korkskruv" "vurkskrok" Övning Definiera en funktion ispalindrome :: String -> Bool som avgör om argumentet är en palindrom. Prelude> ispalindrome "a man a plan a canal panama" True Man bortser från blanktecken i detta test. En bättre funktion skulle också godkänna A man, a plan, a canal Panama! Formattering Kvadratrotstabellen Från i går: [ (x, sqrt x) x <- [1..10] ] Hur får man utskriften som en snygg tabell: 1.0 1.0 2.0 1.41442135623730951 3.0 1.7320508075688772 4.0 2.0 och så vidare? Konvertering Ett första försök Prelude> 3 ++ " " ++ 5 <interactive>:1:15: No instance for (Num [Char]) arising from the literal `5' at <interactive>:1:15 Vi har ett typfel; ++ kan bara konkatenera strängar, inte tal. Funktionen show Funktionen show kan konvertera tal (och annat) till strängar: Prelude> show 3 "3" Prelude> show (2.5 + pi) "5.641592653589793" Prelude> show [1..5] "[1,2,3,4,5]" Ett nytt försök Vad blir resultatet? [ show x ++ " " ++ show (sqrt x) x <- [1.. 10] ] Vi provar förstås. Två preludfunktioner till lines :: String -> [String] unlines :: [String] -> String som delar upp i rader resp sätter samman till en lång sträng med radbytestecken mellan.
Nästan klart Lösningen Nästa försök unlines [show x ++ " " ++ show (x*x) x <- [1.. 10]] Vi provar igen! Sista pusselbiten Vi får precis det resultat vi vill, men som en sträng (ett Haskellvärde av typen String). Det vi skulle vilja i stället är att strängen skrivs ut. Utskriften är en effekt utanför den rena funktionella, matematiska världen. Men i Haskell kan man programmera utskrift av en sträng med preludfunktionen putstr. Prelude> putstr (unlines [ show x ++ " 1.0 1.0 2.0 1.4142135623730951 3.0 1.7320508075688772 4.0 2.0 5.0 2.23606797749979 6.0 2.449489742783178 7.0 2.6457513110645907 8.0 2.8284271247461903 9.0 3.0 10.0 3.1622776601683795 " ++ show (sqrt x) x Kolla att du kan rekonstruera vad som inte ryms på bilden på första raden!