7/14/20151 Haskell: ADT n ADT: pricipi, proprietà n ADT in Haskell: il meccanismo n ADT in Haskell: Hiding e Qualified n Esempi: Store e i problemi di accesso n Accesso: Store con Location importate n Accesso: esportare Location(..) o Location n Esempi: Store e Eq n Esempi: Store come funzione e Show n Esercizi
7/14/20152 ADT: Principi, Proprietà n Principi: –Separazione tra: portata: codice che è nello scope di una definizione o binding accessibilità: codice che può fare riferimento a tale definizione o binding n Proprietà: –Generalizzazione di strutture dati: implementazione: codice con cui è implementato ogni valore strutturato specifica: valori rappresentati, operazioni applicabili e loro comportamento – Indipendenza tra: sviluppo: codice con cui è implementato e chi lo realizza, e successive modifiche delle implementazioni uso: codice che utilizza tali valori e chi ne applica le operazione e successive modifiche delle applicazioni
7/14/20153 ADT in Haskell: il Meccanismo APPLICAZIONI - uso newIntStore:: IntStore value:: IntStore -> Location -> Int update:: IntStore -> Loation -> Int -> IntStore Sviluppo - implementazione n Meccanismo: –Segnatura operazioni accessibile, quindi utilizzabili, sui valori dell’ADToperazioni accessibile, quindi utilizzabili, sui valori dell’ADT attraverso impiego (facoltativo) dei tipi esplicitiattraverso impiego (facoltativo) dei tipi espliciti –Moduli e Hiding dei costruttori di tipi algebrici Struttura di modulo: per controllare accessibilitàStruttura di modulo: per controllare accessibilità module IntStore (--export identifiers con segnatura come commento a destra IntStore, -- IntStore newIntStore, -- IntStore value, -- IntStore -> Location -> Int update -- IntStore -> Location -> Int -> IntStore update -- IntStore -> Location -> Int -> IntStore ) where -- import: moduli importati -- import: moduli importati -- definizioni: dati e operazioni -- definizioni: dati e operazioni Import può restringere accessibilità sugli importatiImport può restringere accessibilità sugli importati Hiding e Qualified: per restringere accessibilità sugli importatiHiding e Qualified: per restringere accessibilità sugli importati
7/14/20154 ADT in Haskell: Hiding e Qualified n Meccanismo: –Import import Location import Location –hiding import Location Hiding (op1,..,opk,Data1,…,Datak) import Location Hiding (op1,..,opk,Data1,…,Datak) op1 -- locale –qualified import Qualified Location import Qualified Location…. Location.op1 -- importata op1 -- locale
7/14/20155 Esempi: Store e i problemi di accesso Cosa cambia se: 1. Locations è un tipo importato? 2. IntStore deve essere confrontabile con equivalenza strutturale 3. IntStore deve essere di classe Show module IntStore (--export identifiers con segnatura come commento a destra IntStore, -- IntStore IntStore, -- IntStore newIntStore, -- IntStore newIntStore, -- IntStore value, -- IntStore -> Location -> Int value, -- IntStore -> Location -> Int update -- IntStore -> Location -> Int -> IntStore update -- IntStore -> Location -> Int -> IntStore )where )where -- import: moduli importati -- definizioni: dati e operazioni data IntStore = Sto[ (Location,Int) ] type Location = String newIntStore:: IntStore newIntStore = Sto [] value:: IntStore -> Location -> Int value(Sto []) v = 0 value(Sto ((u,n):rs)) v | (u==v) = n | (u==v) = n | otherwise = value(Sto rs) v | otherwise = value(Sto rs) v update:: IntStore -> Location -> Int -> IntStore update(Sto s) u n = Sto ((u,n):s) module WorkingModule where import IntStore -- test s0 = newIntStore s1 = update newIntStore "loc0" 26 s2 = update (update s1 "Loc1” 2) "Loc7" 0 s3 = update s2 "Loc0” (-12) ERROR - Cannot find "show" function for: *** Expression : s3 I moduli sono caricati regolarmente Ma cosa succede se valutiamo s3
7/14/20156 Accesso: Store e il problema (1) Module Location ( Location -- il tipo è esportato Location -- il tipo è esportato )where )where data Location = L String module IntStore (--export identifiers con segnatura come IntStore, -- IntStore IntStore, -- IntStore … update -- IntStore -> Location -> Int -> IntStore update -- IntStore -> Location -> Int -> IntStore )where )where -- import: moduli importati import Location -- definizioni: dati e operazioni data IntStore = Sto[ (Location,Int) ] newIntStore:: IntStore newIntStore = Sto [] value:: IntStore -> Location -> Int value(Sto []) v = 0 --value(Sto ((u,n):rs)) v -- | (u==v) = n -- | otherwise = value(Sto rs) v update:: IntStore -> Location -> Int -> IntStore update(Sto s) u n = Sto ((u,n):s) module WorkingModule where import IntStore -- test s0 = newIntStore s1 = update newIntStore (L "loc0") 26 s2 = update (update s1 (L "Loc1") 2) (L "Loc7") 0 s3 = update s2 (L "Loc0") (-12) Il caricamento di IntStore è regolare ERROR - Undefined constructor function "L" Occorre rendere accessibile L anche a chi importa InstStore Location Il caricamento di WorkingModule produce Non basta Mettiamo da parte Eq
7/14/20157 Accesso: Location(..) o Location? Module Location ( Location(L) -- il tipo algebrico è esportato Location(L) -- il tipo algebrico è esportato )where )where data Location = L String module IntStore (--export identifiers con segnatura IntStore, -- IntStore IntStore, -- IntStore Location(..) -- esporta Location con i costruttori Location(..) -- esporta Location con i costruttori … update -- IntStore -> Location -> Int -> IntStore update -- IntStore -> Location -> Int -> IntStore )where )where -- import: moduli importati import Location -- definizioni: dati e operazioni data IntStore = Sto[ (Location,Int) ] newIntStore:: IntStore newIntStore = Sto [] value:: IntStore -> Location -> Int value(Sto []) v = 0 --value(Sto ((u,n):rs)) v -- | (u==v) = n -- | otherwise = value(Sto rs) v update:: IntStore -> Location -> Int -> IntStore update(Sto s) u n = Sto ((u,n):s) module WorkingModule where import IntStore -- test s0 = newIntStore s1 = update newIntStore (L "loc0") 26 Module Location ( Location, -- esportato senza costruttori (ADT) Location, -- esportato senza costruttori (ADT) loc-- String -> Location loc-- String -> Location )where )where data Location = L String loc:: String -> Location loc s = L s module WorkingModule where import IntStore -- test s0 = newIntStore s1 = update newIntStore (loc "loc0") 26 module IntStore (--export identifiers con segnatura IntStore, -- IntStore IntStore, -- IntStore Location, -- esporta ADT Location, -- esporta ADT loc, -- esporta ADT loc, -- esporta ADT … update -- IntStore -> Location -> Int -> IntStore update -- IntStore -> Location -> Int -> IntStore )where )where -- import: moduli importati import Location … update:: IntStore -> Location -> Int -> IntStore update(Sto s) u n = Sto ((u,n):s)
7/14/20158 Esempi: Store e Eq module IntStore (--export identifiers con segnatura IntStore, -- IntStore IntStore, -- IntStore Location, -- esporta Location con i costruttori Location, -- esporta Location con i costruttori loc, -- String -> Location loc, -- String -> Location … update -- IntStore -> Location -> Int -> IntStore update -- IntStore -> Location -> Int -> IntStore )where )where -- import: moduli importati import Location -- definizioni: dati e operazioni data IntStore = Sto[ (Location,Int) ] type Location = String newIntStore:: IntStore newIntStore = Sto [] value:: IntStore -> Location -> Int value(Sto []) v = 0 value(Sto ((u,n):rs)) v | (u==v) = n | (u==v) = n | otherwise = value(Sto rs) v | otherwise = value(Sto rs) v update:: IntStore -> Location -> Int -> IntStore update(Sto s) u n = Sto ((u,n):s) Module Location ( Location -- esportato senza costruttori (ADT) Location -- esportato senza costruttori (ADT) loc -- String -> Location loc -- String -> Location )where )where data Location = L String deriving(Eq) loc:: String -> Location loc s = L s module WorkingModule where import IntStore -- test s0 = newIntStore s1 = update newIntStore (loc "loc0") 26
7/14/20159 Esempi: Store come funzione e Show module IntStore( IntStore, Location(..), Location(..), newIntStore, -- IntStore newIntStore, -- IntStore value, -- IntStore -> Location -> Maybe Int value, -- IntStore -> Location -> Maybe Int update -- IntStore -> Location -> Int -> IntStore update -- IntStore -> Location -> Int -> IntStore ) where import Location data IntStore = Sto (Maybe(Location -> Int)) [Location] dom:: IntStore -> [Location] dom (Sto _ l) = l size:: IntStore -> Int size (Sto _ l) = length l … (continued) module Location( Location(..) Location(..) ) where ) where data Location = L Int deriving(Eq) instance Show Location where show (L n) = "%" ++ (show n) show (L n) = "%" ++ (show n) module WorkingModule where import IntStore -- test s0 = newIntStore s1 = update newIntStore (L 0) 26
7/14/ Esercizi: Store. Modificare il modulo IntStore in modo tale che l’implementazione dell’ADT utilizzi funzioni da Location -> Val. Allo scopo si fornisca anche un ADT per Val di classe Eq e Show. Location -> Val. Allo scopo si fornisca anche un ADT per Val di classe Eq e Show. Store. Modificare le definizioni precedenti in modo tale che Val sia un unione polimorfa di tre differenti tipi, Location sia anche di classe Show, e Store abbia una operazione polimorfa per allocazione e tipi, Location sia anche di classe Show, e Store abbia una operazione polimorfa per allocazione e inizializzazione (al valore di default) delle locazioni. inizializzazione (al valore di default) delle locazioni. Set. Definire un ADT polimorfo per insiemi di valori di tipo a, equipaggiato con valore empty, operazioni union, set, choice, e predicato isIn: tutte con l’usuale significato. In particolare, set, applicato ad un valore union, set, choice, e predicato isIn: tutte con l’usuale significato. In particolare, set, applicato ad un valore di v calcola il singoletto v, mentre choice, applicata ad un Set, s0, non empty, calcola una coppia (u,s1) tali di v calcola il singoletto v, mentre choice, applicata ad un Set, s0, non empty, calcola una coppia (u,s1) tali che: 1) isIn u s0 == False, 2) union (set u) s1 == s0. che: 1) isIn u s0 == False, 2) union (set u) s1 == s0. Set. Si definisca un modulo WSet che importi il modulo Set di esercizio precedente, e fornisca - le operazioni interset, che calcola intersezione, e size, che calcola la cardinalità - le operazioni interset, che calcola intersezione, e size, che calcola la cardinalità - un ADT polimorfo per insiemi di valori di quattro possibili tipi polimorfi. Il nuovo ADT fornisce - un ADT polimorfo per insiemi di valori di quattro possibili tipi polimorfi. Il nuovo ADT fornisce le sole operazioni union, interset, empty e isIn. le sole operazioni union, interset, empty e isIn. unify. Scrivere tre moduli: Terms, Substitution, Unify. Terms contiene un ADT per termini tipi con variabili, funzione, coppia, lista. Substitution contiene un ADT per sostituzioni. Unify contiene una variabili, funzione, coppia, lista. Substitution contiene un ADT per sostituzioni. Unify contiene una funzione che implementa l’algoritmo di unificazione visto nel corso. funzione che implementa l’algoritmo di unificazione visto nel corso.