Două lumi: lumea datelor și lumea tipurilor map :: (a -> b) -> [a] -> [b] expresie de date :: expresie de tip ^ "are tipul" expresie de tip: => *Date* *Tipuri* expresii de date -- au valori expresii de tip -- reprezintă tipuri variabile de date (identificatori) variabile de tip tipuri de bază constructori de date constructori de tip -> construiesc valori -> construiesc tipuri noi pe care le pot folosi în program Tipuri de bază: Int, Integer, Char, Bool, Float pot fi definite ca mulțimi de valori Constructori de tip: "funcții pe tipuri" -- primesc alte tipuri ca argument și construiesc tipuri noi Exemple (,) -- construiește un tip pereche, pe baza a două tipuri existente (,) a Char => tipul pereche dintre tipul a și tipul caracter același nume cu constructorul de date pentru perechi [] -- construiește un tip listă, pe baza unui alt tip existent [] Char => tipul listă de caractere [Char] -> -- construiește un tip de funție pe baza tipului argumentului și pe baza tipului valorii întoarse * expresiile de date sunt asociative stânga 5 + 5 + 5 + 5 ~ ((5 + 5) + 5) + 5 map f [1,2,3] ~ (map f) [1,2,3] map + 1 [1,2,3] ~ ((map +) 1) [1,2,3] -- nu este corect, + nu poate primi un argument de tip map map (+1) [1,2,3] 5 + 3 * 4 ~ 5 + (3 * 4) -- pentru că + are prioritate mai mică decât * mod 5 2 + mod 3 2 ~ + mod 5 2 mod 3 2 * expresiile de tip sunt asociative dreapta map :: (a -> b) -> [a] -> [b] ~ (a -> b) -> ([a] -> [b]) Sinteză de tip ============== "expected type" -- tipul pentru expresie așa cum este așteptat din exterior "actual type" -- tipul determinat al expresiei, pe baza componentelor ei *Exemplul 1* f g = (g 3) + 1 f = \g -> (g 3) + 1 mă uit la f și la definiția pentru f f :: a f :: b -> c a = b -> c TLambda: g :: b (g 3) + 1 :: c mă uit la (g 3) și la regula TApp (g 3) :: d 3 :: Int din TInt g :: Int -> d mă uit la expresia (g 3) + 1 și la regula T+ (g 3) + 1 :: Int (g 3) :: Int 1 :: Int adevărat și cf TInt d = Int b = Int -> d = Int -> Int c = Int f :: a = b -> c = (Int -> Int) -> Int *Exemplul 2* fix f = f (fix f) fix = \f -> (f (fix f)) mă uit la fix și la regula TLambda: fix :: a -> b f :: a (argument al lui fix) f (fix f) :: b mă uit la (f (fix f)) și la regula TApp: (f (fix f)) :: d f :: c -> d (fix f) :: c mă uit la (fix f) și la TApp: (fix f) :: g fix :: e -> g f :: e fix: a -> b = e -> g a = e b = g f: a = e = c -> d fix f: c = g (f (fix f)): b = d fix :: a -> b = (c -> d) -> b = (b -> b) -> b *Exemplul 3* f x = (x x) f = \x -> (x x) TLambda: f :: a -> b x :: a (x x) :: b TApp: (x x) :: d x :: c -> d x :: c x: a = c = c -> d = a -> b a nu poate fi același tip cu a->b pentru că este un tip ciclic expresia nu poate fi tipată. occurs check verifică dacă în legarea unei variabile de tip la un tip mai detaliat, variabila apare în interiorul tipului mai detaliat Test ---- let m f l | l==[] = [] | True = f (head l) : m f (tail l) in m (+1) [1..] m :: a -> b -> c a = (d -> e) b = [g] d = g m :: (d -> e) -> [d] -> [e] Tipuri de date utilizator ========================= * construcție pe baza altor tipuri -- ca alias al altor tipuri * type -- alias pentru alt tip * folosesc noul tip în expresii de tip * newtype -- alias, dar în același timp un tip nou * construcție de tipuri noi, ca TDA TDA: constructori de bază -- funcții care permit construcția oricărei valori din tip [operatori, axiome care arată cum funcționează operatorii] data FuzzyBoolean = CertainTrue | CertainFalse | Fuzzy constructorii de date: * pot apărea în afișarea valorilor tipului * pot fi folosiți în pattern-matching data = constructor de date | constr de date ... constructor de date = expresiile de tip pot conține variabile Point-free programming ---------------------- Definirea de funcții fără specificarea explicită a argumentelor operatorul $ este echivalent cu aplicarea unei funcții $ are prioritatea cea mai mică (dar mai mare decât construcții sintactice, e.g. if, let, where, case, etc) f $ arg ~ (f arg) f x (g y) ~ f x $ g y $ folosesc atunci când am o paranteză dintr-un anumit punct până la sfârșitul expresiei curente $ are asociativitate dreapta f $ g x y $ h 3 $ t ~~ f (g x y (h 3 (t))) operatorul . -- compunerea de funcții (în sensul matematic) f x = g (h x) ~ f x = (g . h) x ~ f = g . h *! nu confundați . cu $* f x = g $ h x ~ f x = (g . h) x DAR f = g $ h nu este același lucru cu f = g . h f = g $ h ~ f = (g h) în expresia cu $ g primește ca argument pe h