------------------------------------------------------------ Dobry kurs: www.schoolofhaskell.com/school/starting-with-haskell/introduction-to-haskell Dobra książka: learnyouahaskell.com ------------------------------------------------------------ HASKELL jest językiem funkcyjnym --> wszystko ma strukturę i jest traktowane jak matematyczna funkcja infix function - pisana pomiędzy argumentami, np. 5 * 2.0 92 `div` 10 prefix function - pisana przed listą argumentów, np. (*) 5 2.0 div 92 10 succ 8 Jest to język silnie typowany (o ścisłej kontroli typów). Typy są pogrupowane w klasy, aby można było stosować polimorficzne definicje funkcji. Glasgow Haskell Compiler GHC Praca interaktywna poprzez powłokę ghci Kompilacja programów za pomocą: ghc plik_źródłowy.hs ghc plik_źródłowy.hs -o plik_wynikowy.exe Plik .hs musi mieć zadeklarowaną funkcję main, czego nie trzeba robić w powłoce ghci. Wbrew pozorom, użycie ghci jest trudniejsze, niż zwykłe kompilowanie plików z kodem. 01. Pierwsza funkcja. Przykładowa sesja w ghci [marek LAB05-haskell]$ echo "podwoj x = x + x" > test.hs [marek LAB05-haskell]$ ghci GHCi, version 7.4.2: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude> :load test.hs [1 of 1] Compiling Main ( test.hs, interpreted ) Ok, modules loaded: Main. *Main> podwoj 4 8 *Main> podwoj 14.6 29.2 *Main> Leaving GHCi. o Argumenty funkcji podaje się bez nawiasów, chyba, że są to "krotki". o Nazwy funkcji nie zaczynają się wielkimi literami. o Apostrof po nazwie funkcji zwyczajowo oznacza "strict function", w odróżnieniu od szybszej "lazy function", ale nie ma znaczenia syntaktycznego. 02. Listy (tablice) - muszą zawierać elementy tylko jednego typu o Dodawanie list [1,2,3] ++ [3,4,1] "Hello" ++ " " ++ "world!" ['H','a','s'] ++ ['k','e','l','l'] o Rozszerzenie listy o element(y) na początku 'T' : "o jest kotek" 1:2:3:[] o Deklaracje list [] lista pusta [[]] lista zawierająca listę pustą [[],[],[]] lista zawierająca 3 listy puste a=[1..10] a=['a'..'z'] a=[2,4..20] Przykład z ghci: Prelude> let a = [2,4..20] Prelude> print a [2,4,6,8,10,12,14,16,18,20] Prelude> let a = [2,5..20] Prelude> print a [2,5,8,11,14,17,20] Prelude> let a = [2,6..20] Prelude> print a [2,6,10,14,18] o Pobranie elementu listy (indeksowane od zera) "Haskell!" !! 3 o Porównywanie list. Jeśli ma to logiczny sens, listy mogą być porównywane element po elemencie, aż do ustalenia wyniku. Operatory porównania to < <= > >= == o Podstawowe operacje na listach a=[1,2,3,4,5] /uwaga: w ghci deklaracja przez let a=[1,2,3,4,5]/ head a tail a last a init a length a null a sprawdza, czy lista jest pusta reverse a take 2 a bierze 2 pierwsze elementy listy take 10 a take 0 a drop 2 a opuszcza 2 pierwsze elementy listy drop 0 a drop 10 a minimum a maximum a sum a product a elem 2 a sprawdza, czy '2' jest elementem z listy 2 `elem` a 10 `elem` a cycle [1,2,3] take 10 (cycle [1,2,3]) repeat 5 replicate 20 "Haskell" \__ te dwie deklaracje take 20 (repeat "Haskell") / są sobie równoważne Więcej operacji na listach znajduje się w predefiniowanym module import Data.List intersperse 3 a 03. "Krotki", "N-tki" (tuples) o Mają z góry zadeklarowaną długość o Nie muszą zawierać elementów tego samego typu fst (1,2) Pierwszy element z pary snd (2,3) Drugi element z pary zip Scala krotki ucinając nadmiarowe elementy zip [1..] ["ziemniak","pilot","pies","kot"] ------------------------------------------------------------ Przykłady: definicje zbiorów ------------------------------------------------------------ [x*2 | x<-[1..10]] [x*2 | x<-[1..10],x*2>=12] [x | x<-[50..100], x `mod` 7 ==3] [x++" "++y | x<-["czerwony","zielony","czarny"],y<-["pomidor","glut"]] [x | x<-"CZerwony kAptuRek_ PowRaca do Lasu", x `elem` ['A'..'Z']++['_']] ------------------------------------------------------------ Przykład: trójkąty ------------------------------------------------------------ Definiujemy trójkąty o bokach a, b, c nie dłuższych niż 10 trojkaty = [(a,b,c) | a<-[1..10],b<-[1..10],c<-[1..10],a+b>c,b+c>a,c+a>b] trprost = [(a,b,c) | (a,b,c)<-trojkaty, a^2+b^2==c^2] trrownob = [(a,b,c) | (a,b,c)<-trojkaty, a==b, b==c] ------------------------------------------------------------ 04. Instrukcje warunkowe - kilka konstrukcji. Ważne wcięcia! Funkcja signum zwraca znak liczby { 1, gdy x>0 sgn(x) = { 0, gdy x=0 {-1, gdy x<0 ------------------------------------------------------------ sgn1 :: Integer -> Integer sgn1 n = if n>0 then 1 else if n==0 then 0 else -1 sgn2 :: Integer -> Integer sgn2 n | n>0 = 1 | n==0 = 0 | n<0 = -1 sgn3 :: Integer -> Integer sgn3 0 = 0 sgn3 n | n>0 = 1 | n<0 = -1