Haskell Development in Practice Generalizing the problem n
Haskell: Development in Practice Generalizing the problem n Simplifying the problem n Design choices n Auxiliary functions n Esercizi n 1/23/2022 1
Generalizing n Un esempio – Vogliamo esprimere un calcolo per tutti i naturali minori di dato m: » – Pensiamo una soluzione ricorsiva: » – [0. . m] = 0: [1. . m] Ma ora dobbiamo trovare una soluzione per » n [0. . m] [1. . m] Generalizing: risolvere un P – Risolvere un problema più generale Q » Q -- [n. . m] = | (n>m) = [] | otherwise = n: [n+1. . m] – Ottenere la soluzione di P come istanza di Q 1/23/2022 » P --’ [. . ]’ 1 m 2
Simplifying n Un esempio – Vogliamo esprimere un calcolo per riconoscere sequenze di caratteri formanti palindromi » – Pensiamo una soluzione semplificata che operi su stringhe senza caratteri speciali » – simple. Pal. Check st = reverse st == st Adattiamo soluzione » » n “Madam I’m Adam” simple. Pal. Check(“Madam I’m Adam”) calcola false ma: pal. Check(“Madam I’m Adam”) where pal. Check = simple. Pal. Check. clean Calcola true se clean rimuove tutti i caratteri speciali (spazi inclusi) Simplifying: risolvere un P su dominio E – Risolvere il problema P su dominio semplificato D » – Fornire una trasformazione da E a D » – 1/23/2022 FP, D --- soluzione di P su D TE->D Componiamo le soluzioni » FP, E = FP, D. TE->D --- soluzione di P su E 3
Design Choices n Un esempio: Vogliamo esprimere la funzione clean (ovvero la trasformazione di prima) che a) rimuove le Special e b) trasforma in lettere minuscole » – Una prima soluzione: » – clean st = [to. Small ch | ch <- st , not. Special ch] Una terza soluzione » n clean = (filter not. Special). (map to. Small) Una seconda soluzione » – “Madam I’m Adam” => “Madam. Im. Adam” => “madamimadam” clean [] clean (x: xs) = let n = from. Enum x in if (n>96 && n<123) then x: (clean xs) else if (n>64 && n<91) then (to. Small x): (clean xs) else (clean xs) Design: – – – Strutturare evidenziando i componenti: prima e seconda » Terza: filter not. Special non più visibile Ridurre (sotto-)espressioni non libere: prima » Seconda: 1) st libero in list-Comprehension, 2) ch libero in to. Small ch Aiuta a: n n n 1/23/2022 n individuare proprietà, condurre verifiche, apportare modifiche, riusare codice 4
Auxiliaries n Un esempio – – Vogliamo esprimere la funzione subseq che riconosce se il primo argomento è sottostringa del secondo argomento: Pensiamo una soluzione per casi: » – subseq [] _ = True subseq (x: xs) [] = False subseq (x: xs) (y: ys) = …. Completiamo il caso generale con una soluzione ricorsiva: » » Esprimiamo che la soluzione è: i) sottosequenza iniziale, ii) oppure sottosequenza della seconda privata del primo carattere. Occorre una funzione front. Seq per la sottosequenza iniziale: n n subseq (x: xs) (y: ys) = front. Seq (x: xs)(y: ys) || subseq (x: xs) ys Auxiliaries: – front. Seq può essere definita come locale – Programmazione strutturata guidata da decomposizione in sottoproblemi e algoritmi basati su induzione (ricorsione) individua e fa uso di ausiliarie 1/23/2022 5
Briciole: tuple e liste sono funzioni n triple – – n sequence – – – 1/23/2022 [n, m, k] = pred -> pred n m k sel 1 = h -> f -> g -> h sel 2 = h -> f -> g -> f sel 3 = h -> f -> g -> g [n, m] = pred -> pred n m head = f -> g -> f tail = f -> g -> g cons = x -> xs -> [x, xs] nil = x -> x 6
Esercizi: n sep applicata ad un predicato p ed ad una lista ls pone nella prima di una coppia di liste, tutti gli elementi di ls che “soddisfano” p e nella seconda tutti quelli che lo “falsificano”. – a) si esprima sep ricorrendo a due applicazioni di filter – b) si mostri come sep sia una generalyzing di filter e come quest’ultima potrebbe essere ottenuta come istanza di sep – c) si dia una definizione di sep senza ricorrere a filter. n 1/23/2022 sort 100 utilizzando sep, si fornisca una definizione di sort. L che implementa il quicksort su liste di interi, possibilmente ripetuti, nell’intervallo [0. . 100]. Si discuta se, e dove la definizione, faccia uso di simplifying e generalyzing. 7
Esercizi: una soluzione sep a) sep: : ord a => p -> [a] -> ([a], [a]) sep p = ls -> ((filter p ls), ((filter (not. p) ls)) b) filter = fst. sep c) sep p [] = [] sep p (x: xs) | (p x) = ((x: tt), ff) | otherwise = (tt, (x: ff)) where (tt, ff) = sep p xs sort 100 sort [] = [] sort (x: xs) | (xs==[]) = [x] | otherwise = (sort tt) ++ [x] ++ (sort ff) where (tt, ff) = sep x xs 1/23/2022 8
- Slides: 8