Questa sezione e' composta da tre parti: ESERCIZI LAMBDA-CALCOLO, ESERCIZI HASKELL e ESERCIZI PROGRAMMAZIONE HASKELL
ESERCIZI LAMBDA CALCULUS
Esercizio 0
Cosa si intende per "programma" nel contesto dei linguaggi di programmazione funzionale?
In cosa consiste l'"esecuzione" di un programma in un linguaggio funzionale?
Elencare alcuni concetti tipici della programmazione imperativa che perdono
completamente di significato in quella funzionale.
Cos'e' un Modello Computazionale?
Cosa si intende per "astrazione funzionale"
e come questa viene formalizzata nel lambda-calcolo?
Cosa si intende per "currificazione"
e quali sono i possibili vantaggi del suo utilizzo.
Cos'e' la relazione di alfa-convertibilita' tra termini?
Esercizio 1
Dato il seguente termine, cerchiare le sue variabili libere e collegare,
utilizzando delle frecce, le sue variabili legate con i lambda relativi.
λz.( ((λx.λx.yx)x)(vλz.λw.v) )
Soluzione.
Esercizio 2
Descrivere sinteticamente alcuni svantaggi dei linguaggi di programmazione
funzionali.
Soluzione.
Esercizio 3
Ridenominare alcune variabili legate nel seguente termine, in modo
che non ci siano due lambda che leghino variabili con lo stesso nome.
(λxxx.(zλz.x))(xλy.(y(λy.z)yy))
Soluzione.
Esercizio 4
Ricopiare il seguente termine sottolineando le variabili libere e mettendo un
cerchietto intorno a quelle legate:
(λx.(z(λz.((xyz)x))zx))x(λx.((λy.yy)(λz.zz)))
Soluzione.
Esercizio 5
Rinominare le variabili legate nel seguente termine in modo che
non ci siano due variabili legate con lo stesso nome
x(λx.((λx.x)x))
Esercizio 6
Fornire un lambda-termine che contenga
variabili con nome x, y e z ed in cui ci siano occorrenze sia legate che libere
di variabili con tali nomi.
Soluzione.
Esercizio 7
Riscrivere il seguente termine utilizzando il minimo numero
di parentesi secondo le convenzioni sintattiche
((xy)(λy.(λz.(z(xy)))))
Soluzione.
Esercizio 8
Supponendo di non utilizzare le convenzioni sintattiche sulle parentesi,
riscrivere il seguente termine inserendo tutte le possibili parentesi.
(λxyz.xy(xz))λxy.x
Soluzione.
Esercizio 9
Definire la nozione di "Currificazione". E' una nozione applicabile al lambda-calcolo? perche'?
Soluzione.
Esercizio 10
Fornire la definizione formale di sostituzione.
Esercizio 11
Qual e' la condizione che deve essere soddisfatta affinche' sia
possibile applicare una sostituzione senza produrre "effetti
indesiderati"?
Esercizio 12
Eseguire le seguenti sostituzioni
-
λy.y(λz.xz)[λz.y / x]
-
x(λyx.x)[(yz)/x]
-
x(λyx.zx)[(λy.y)/x, x/z]
Esercizio 13
Eseguire le seguenti sostituzioni:
-
(λx.yx)[yz/x]
-
(λy.xy)[yz/x]
-
(λz.(λx.yx)xz)[zx/x]
Esercizio 14
Eseguire la seguente sostituzione:
z(λy.wy)λz.((λx.yx)xz) [yz/x,yz/w]
Esercizio 15
Dire qual e' il risultato della seguente sostituzione:
((λy.xy)(λz.y(λy.x)))[xyz/x]
Esercizio 16
Dire qual e' il risultato della seguente sostituzione:
((λy.yy)y(λy.y(λy.y)))[λy.zy/y]
Esercizio 17
Qual e' il risultato delle seguenti sostituzioni?
- λy.x(λx.x)[λy.yx/x]
- y(λz.xz)[λyzy.x/x]
- λy.y(λz.xz)[(λz.y)/(λz.xz)]
Esercizio 18
Qual e' il risultato della seguente sostituzione?
((λw.(xw))(λy.(yx)))[λx.(w(xy))/x]
Esercizio 19
Eseguire le seguenti sostituzioni:
- (λz.z)[( (λy.(xy))[wy/x] )/z]
- (λx.(λz.(xy)))[( (λy.(xy))[wy/x] )/z]
- ((λy.xy)(λz.y(λy.x)))[xyz/x]
Esercizio 20
Qual e' il risultato delle seguenti sostituzioni? Quali sono gli insiemi delle
variabili legate e libere dei termini ottenuti?
- xyy[x/y]
- (λx.zλz.yλy.xyz) [zy/x,xz/y]
Esercizio 21
Qual e' la condizione che deve essere necessariamente soddisfatta per poter correttamente
effettuare una sostituzione M[N/x] ?
Perche' tale condizione e' necessaria?
Esercizio 22
Eseguire le seguenti sostituzioni:
-
(λx.yx)[yz/x]
-
(λy.xy)[yz/x]
-
(λz.(λx.yx)xz)[zx/x]
Esercizio 23
Fornire la definizione esplicita dell'insieme di tutti i lambda-termini
in forma normale (descrivere, in modo ricorsivo, la forma che deve
avere un termine in forma normale).
Soluzione.
Esercizio 23.5
Qual e', se esiste, la forma normale del seguente termine? (\x.yy)((\z.z)x))
Esercizio 24
Trovare la forma normale di
(λxxxx.xx)(λx.xx)(λx.x)y((λx.x)x)
Soluzione.
Esercizio 25
Trovare la forma normale di
(λx.((λy.z)x))((λx.xx)(λx.xx))
Esercizio 26
Trovare la forma normale di
(λx.((λy.z)x))((λx.xx)(λx.xx))
Dire inoltre se questo termine e'
fortemente normalizzabile.
Esercizio 27
Qual e' la formal normale del seguente termine?
((λw.(xw))(λy.(yx)))[λx.(w(xy))/x]
Qual e' l'insieme delle sue variabili libere? e quale quello delle
sue variabili legate?
Esercizio 28
Fornire un lambda-termine normalizzabile il cui insieme di variabili
libere sia {x, y}, e tale che l'insieme delle variabili libere della
sua forma normale sia {x, y, z}.
Soluzione.
Esercizio 29
Fornire un lambda termine che si riduca a forma normale in due passi
di riduzione. Inoltre tale termine deve avere {x, y, z} come insieme
di variabili libere, mentre le variabili libere della sua forma normale
dovranno essere {x, y}.
Soluzione.
Esercizio 30
Portare in forma normale, se esiste, il seguente lambda-termine:
(λx.((λz.zwz)(((λxyx.y)(λx.y)(λy.x))((λx.xx)(λy.yyy)))))t
Soluzione.
Esercizio 31
Qual e' la forma normale, se esiste, del seguente lambda-termine?
(λx.xxy)(λxy.xyy)
Soluzione.
Esercizio 32
Dire in quale caso e' possibile avere un lambda-termine con piu' di una
forma normale.
Soluzione.
Esercizio 33
Qual e' la forma normale, se esiste, del seguente lambda-termine?
(λxy.yx)(λxy.x(yy))(λx.xz(λy.yy))
Soluzione.
Esercizio 34
Qual e' la forma normale del seguente termine?
((λw.(xw))(λy.(yx)))[λx.(w(xy))/x]
Qual e' l'insieme delle sue variabili libere? e quale quello delle
sue variabili legate?
Esercizio 35
Dire se il seguente termine possiede forma normale ed eventualmente fornirla insieme
ai vari passi di riduzione:
(λxxx.((λxx.x)(xx)(λx.x)))x(xx)
Soluzione.
Esercizio 36
Dire in quale caso e' possibile avere un lambda-termine con una sola
forma normale.
Soluzione.
Esercizio 37
Esercizio 38
Dimostrare che se un termine M contiene Omega ( (λx.xx)(λx.xx) ) come
sottotermine proprio, allora non e' normalizzabile (non possiede forma normale).
Soluzione.
Esercizio 39
Enunciare e dimostrare il Corollario di Unicita' della forma
normale.
Esercizio 40
Fornire la definizione di alfa-conversione. Qual e' il motivo per introdurre
tale nozione nel lambda-calcolo?
Esercizio 41
Esercizio 42
Esercizio 43
Fornire un lambda termine che sia normalizzabile, ma a partire dal quale esiste
anche una sequenza infinita di beta-riduzioni.
Esercizio 44
Cos'e' una strategia di riduzione?
Esercizio 45
Cosa si intende per strategia di riduzione Call-by-value?
Esercizio 46
Esercizio 47
Dare la definizione di strategia di riduzione, strategia di riduzione call-by-value,
strategia di riduzione call-by-name, strategia leftmost-outermost.
La strategia leftmost-outermost e' call-by-value o call-by-name ?
Esercizio 48
Esercizio 49
Esercizio 50-67
Esercizio 68
Dimostrare che se P -->beta Q
allora FV(Q) e' un sottoinsieme di FV(P).
Soluzione.
Esercizio 69
Esercizio 70
Spiegare perche' talvolta, prima di eseguire una beta-riduzione,
occorra rinominare le variabili legate (della lambda astrazione).
In tali casi, si riuscirebbero ad evitare problemi se si operasse invece
sulle variabili dell'argomento della beta riduzione? Motivare.
Esercizio 71
Trovare tre termini M,P e Q,
tali che M contiene x e y tra le sue variabili libere e tali che
M[P/x,Q/y] sia diverso da M[P/x][Q/y]
Esercizio 72
Esercizio 73
Dimostrare che il lambda-termine
(λx.xxx)(λx.xxx)
non e' normalizzabile.
Soluzione.
Esercizio 74
Esercizio 75
Enunciare il Teorema di Confluenza del λ-calcolo ed utilizzarlo per
dimostrare la proprieta' di unicita' della forma normale.
Esercizio 76
Fornire la definizione formale di sostituzione per il lambda-calcolo.
Trovare poi tre termini M,P e Q, tali che M contenga x e y tra le sue variabili
libere e tali che M[P/x,Q/y] sia diverso da M[P/x][Q/y]
Soluzione.
Esercizio 77
Definire formalmente la nozione di sostituzione nel λ-calcolo.
Effettuare la seguente sostituzione e ridurre il termine ottenuto, se possibile,
in forma normale.
((λw.(xw))(λy.(yx)))[λx.(w(xy))/x]
Soluzione.
ESERCIZI HASKELL
Esercizio 1
Soluzione
Esercizio 2
Supponete di aver definito una funzione Haskell di nome funct.
Dire cosa fa il sistema se si scrive:
:type funct
Dire cosa avrebbe fatto il sistema se prima della definizione di funct uno avesse scritto:
funct :: [Int] -> Bool
Soluzione
Esercizio 3
Definire in HASKELL il tipo di dato astratto Albero binario etichettato con etichette
numeriche.
Soluzione
Esercizio 4
Definire in HASKELL il tipo di dato astratto Albero ternario senza etichette.
Soluzione
Esercizio 5
Definire in Haskell il tipo di dato Albero ternario etichettato.
Discutere brevemente la soluzione proposta.
Soluzione
Esercizio 6
Esercizio 7
Supponendo che non sia predefinito, definire in HASKELL il tipo di dato astratto
Lista di Interi. E' possibile definire il tipo di dato Lista di elementi qualsiasi?
Soluzione
Esercizio 8
Esercizio 9
La sonda Spirit ha trovato che su Marte esistono i Loffioni.
Un Loffione puo' essere un Gangarone oppure un Sarrapone,
oppure una sequenza finita di Purpuroni.
Un Purpurone e' formato da un Gangarone e un Sarrapone.
In natura il numero di sarraponi e' infinito, invece esistono solo due Gangaroni,
il GangaroneA e il GangaroneB.
Definire in Haskell il tipo di dato astratto Loffione che possa permettere
di scrivere programmi Haskell che simulino esperimenti virtuali sui Loffioni.
Soluzione
Esercizio 10
Le seguente definizioni HASKELL
f n = n:(f(n+1))
nums = f 0
corrispondono, in SCHEME, a
(define (f n) (cons n (f (+ n 1))))
(define nums (f 0))
Che cosa "dovrebbe" fare f? e cosa e' nums?
Perche' in Haskell possiamo utilizzare f e nums (fornire possibilmente
un esempio di uso), mentre in SCHEME non ci possiamo fare in pratica niente?
Perche' comunque, anche se poi non ci possiamo fare un fico secco, SCHEME permette
lo stesso di definire la funzione f senza darci problemi?
Soluzione
Esercizio 11
Presa la seguente definizione di tipo in HASKELL
data Pirimpo = Pompero Int | Zumpo Pirimpo [Int]
scrivere delle definizioni Scheme che permettano di utilizzare
(per qual che e' possibile in Scheme) il tipo di dato Pirimpo.
Soluzione
Esercizio 12
Gli Yunz sono esseri magici che nella contea di Hargaar vengono
usati dagli studenti per passare gli esami.
Uno Yunz puo' venire generato dicendo due numeri qualsiasi mentre
si effettua l'incantesimo del mago Frunz su due Yunz. Il nanetto Yor e'
uno Yunz.
- Definire il tipo di dato Yunz in Haskell.
- Affinche' uno studente possa trarre profitto dalla presenza
di uno Yunz, deve sapere se per generarlo e' mai stato utilizzato il
numero 276 durante l'incantesimo del mago Frunz. Definire un predicato
Haskell che serva a tale scopo.
Esercizio 13
Dire brevemente cosa fa' l'interprete HASKELL quando scriviamo qualcosa
del genere:
funct :: [Int] -> Bool
funct ls = BODY
Esercizio 14
Soluzione
Esercizio 14
Esercizio 15
Esercizio 16
Esercizio 17
Esercizio 18
Esercizio 19
Si consideri la seguente funzione Haskell:
myPenultimo (x) | (length x)==1 = x
| (length x)==2 = head x
| otherwise = myPenultimo(tail x)
L'interprete restituisce il seguente errore
Occurs check: cannot construct the infinite type: a0 = [a0]
Expected type: [[a0]]
Actual type: [a0]
In the first argument of `head', namely `x'
In the expression: head x
In an equation for `myPenultimo':
myPenultimo (x)
| (length x) == 1 = x
| (length x) == 2 = head x
| otherwise = myPenultimo (tail x)
Failed, modules loaded: none.
Perche'?
Modificare inoltre la funzione in modo che restituisca il penultimo elemento di una lista
(definendo penultimo di [] come [] e penultimo di una lista con un solo elemento come
l'unico l'elemento).
Soluzione
ESERCIZI PROGRAMMAZIONE HASKELL
Esercizio 1
Scrivere la funzione Haskell "pippo" che corrisponde al lambda termine
\xy.yx
Come si puo' fare in modo che, senza modificare la definizione
della funzione pippo, questa possa accettare solo elementi numerici come
primo input?
Possibile soluzione.
Esercizio 2
Definire una funzione Haskell ricorsiva che prenda in input un
numero naturale n e calcoli la somma di tutti i numeri pari da 0 a n.
(Usare il predicato Haskell che controlla se un numero e' pari )
Esercizio 3
Definire in Haskell la funzione "manoh" che, preso un numero n,
restituisce la somma dei quadrati dei naturali da 0 ad n.
Esercizio 4
Definire in Haskell la funzione "mavah" che, preso un numero n,
restituisce il quadrato della somma dei naturali da 0 ad n.
Esercizio 5
Definire in Haskell la funzione "madaih" che, preso un numero n,
restituisce la somma dei naturali da 0 ad n.
Esercizio 6
Definire in Haskell la funzione "masih" che, preso un numero n,
restituisce il quadrato della somma dei naturali da 0 ad n.
Esercizio 6.5
Supponiamo di aver definito in Scheme una funzione a valori booleani (un predicato) "cucu".
Definire una funzione Scheme che, dati in input due numeri naturali n ed m (n ≤ m), restituisca la somma di tutti i numeri compresi tra n ed m che soddisfano il predicato "cucu".
Esercizio 7
Fornire una funzione Haskell che, preso in input un predicato p
sui naturali restituisca una funzione sui naturali che vale 2 sui
numeri su cui p e' vero e 3 sui numeri su cui
p e' falso.
Esercizio 8
Esercizio 8.1
Esercizio 9
Esercizio 10
Esercizio 11
Definire la funzione Haskell che implementi l'insertion sort su liste,
avendo come parametro anche la relazione di precedenza.
Possibile soluzione.
Esercizio 12 (un po' complesso)
Definire la funzione Haskell che, dato un grafo e due nodi, restituisca
l'insieme dei cammini (privi di cicli) dal primo al secondo nodo.
Possibile soluzione.
Esercizio 13
Definire in Haskell i tipi di dato Abn ("Albero binario con etichette numeriche")
e Abf ("Albero binario con etichette di tipo Int -> Int").
Definire due semplici elementi di tipo Abn e Abf.
Definire una funzione Haskell
appT :: Abf -> Abn -> Abn
che prenda un albero Abf ed uno Abn con la stessa struttura (non occorre
implementare il controllo che abbiano la stessa struttura) e restituisca
un albero Abn (con la stessa struttura degli alberi in input) in cui le
etichette corrispondano alle applicazioni delle funzioni dell'albero Abf
ai numeri dell'albero Abn.
Nel caso di alberi con struttura differente, e volendo gestire
tale situazione non con la generazione di un messaggio di errore,
si potrebbe utilizzare la monade Maybe.
Ridefinire quindi la funzione appT in modo che abbia il seguente tipo
appT :: Abf -> Abn -> (Maybe Abn)
Possibile soluzione.
Esercizio 14
Esercizio 15
Definire in Haskell la lista di tutti i numeri
naturali a partire da 1.
Utilizzarla per definire la funzione che, preso un
predicato sui numeri, restituisca la lista di tutti
i numeri che soddisfano il predicato.
Possibile soluzione.
Esercizio 16
Utilizzare l'esercizio 15 per definire la
lista di tutti i multipli comuni a due numeri
e da questa la funzione che calcoli il minimo comune
multiplo.
Possibile soluzione.
Esercizio 17
Definire il tipo di dato parametrico degli
alberi etichettati in cui ogni nodo puo' avere
un numero arbitrario di figli.
Definire quindi la funzione innesta che, presa in input
un'etichetta label e due alberi, inserisca il secondo
albero come primo figlio di tutti i nodi del primo
albero che hanno label come etichetta.
Rendere il tipo di dato membro della
classe Eq, in modo che sugli alberi la
funzione di uguaglianza corrisponda all'uguaglianza della
loro struttura, senza considerare le etichette.
Possibile soluzione.
Esercizio 18
La seguente funzione Scheme prende in input un predicato su numeri una lista ls contenente
numeri o liste di numeri a qualsiasi livello di annidamento
e restituisce una lista uguale ad ls, ma con 0 al posto dei numeri che
soddisfano il predicato p?
define (guess p? ls)
(if (null? ls)
'()
(cons (cond
( (not (number? (car ls))) (guess p? (car ls)) )
( (p? (car ls)) 0 )
( else (car ls) ) )
(guess p? (cdr ls)) ) ) )
Scrivere una funzione Haskell che faccia la stessa cosa.
Possibile soluzione.
Esercizio 19
Definire in Haskell la lista di tutti i numeri naturali a partire da 1.
Utilizzarla per definire la funzione che, preso un predicato sui numeri, restituisca
la lista di tutti i numeri che soddisfano tale predicato.
Esercizio 20
La sonda Spirit ha trovato che su Marte esistono i Loffioni.
Un Loffione puo' essere generato da un Gangarone oppure da un Sarrapone,
oppure da una sequenza finita di Purpuroni.
Un Purpurone viene generato dall'incontro di un Gangarone e un Sarrapone.
Su Marte ci sono infiniti sarraponi, ma solo due Gangaroni,
il GangaroneA e il GangaroneB.
Definire in Haskell il tipo di dato astratto Loffione che possa permettere
di scrivere programmi Haskell che simulino esperimenti virtuali sui Loffioni.
Scrivere il programma Haskell che, preso un Loffione, restituisca
quante volte il GangaroneA e' intervenuto nella generazione del Loffione dato.
Possibile soluzione.
Esercizio 21
Programmare la funzione quicksort in Haskell e Erlang, senza ricorsione di coda.
Possibile soluzione.
Esercizio 22
Esercizio 23
Supponiamo di aver bisogno, dati due tipi A e B,
di lavorare con liste contenenti elementi di A e B alternati.
Definire in Haskell tale tipo di dato. Utilizzarlo poi
per definire una funzione "divide" che, presa una lista ls
di Int e Bool alternati, restituisca la coppia formata dalle
due liste ottenute considerando solo gli elementi Int e quelli
Bool in ls.
Il tipo coppia e' denotato in Haskell con (T1,T2). Il costruttore
di coppie e', similmente, (e1,e2). "fst" e' la funzione che restituisce
il primo elemento di una coppia, "snd" il secondo.
Possibile soluzione.
Esercizio 24
Discutere brevemente della Tail Recursion.
Il seguente codice Haskell implementa l'insertion-sort parametrizzato
sul un predicato di precedenza, prec.
insert el [] prec = [el]
insert el (x:xs) prec = if (prec el x)
then (el:(x:xs))
else (x:(insert el xs prec))
insertionsort [] prec = []
insertionsort (x:xs) prec = (insert x (insertionsort xs prec) prec)
Fornire una versione tail-recursive dell'insertion-sort.
(se servissero, si puo' supporre di avere a disposizione le versioni
tail-recursive dell'append e del reverse: appendIt e reverseIt).
Possibile soluzione.
Esercizio 25
Scrivere un programma Haskell che produca la lista di tutti i possibili cammini
tra due nodi forniti in input in un grafo non orientato
(anch'esso fornito in input).
Il grafo e' rappresentato da una lista di archi, rappresentati a loro volta da
coppie di nodi. I nodi sono rappresentati da numeri interi.
Si supponga che se un arco e' rappresentato dalla coppia (n,m), allora il grafo
non contiene anche la coppia (m,n).
archi
Possibile soluzione.
Esercizio 25.1
Modificare il programma dell'esercizio 25 definendo il tipo grafo
come
type Graph = (Set Node, (Node -> (Set Node)))
Esercizio 26
Si fornisca una soluzione dell'esercizio 25 in modo che la chiamata ricorsiva
del programma abbia sempre lo stesso grafo come argomento.
Possibile soluzione.
Esercizio 27
Esercizio 28
Fornire una soluzione che usi ricorsione di coda per l'esercizio 25.
Possibile soluzione.
Esercizio 29
Definire in Haskell il tipo di dato astratto
Albero Binario con rami infiniti e con nodi con etichette di tipo parametrico a.
Costruire poi l'albero infinito con etichette numeriche
della forma:
1
/ \
/ \
/ \
2 3
/ \ / \
4 5 6 7
/ \ / \ / .......
8 9 10 11 12 ........
.......................
Possibile soluzione.
Esercizio 30
Sia
data InfNBT = Join Int InfNBT InfNBT
il tipo di dato degli alberi binari con rami infiniti ed etichette numeriche.
Si definisca myIT come il seguente elemento di InfNBT
1
/ \
/ \
/ \
2 3
/ \ / \
4 5 6 7
/ \ / \ / .......
8 9 10 11 12 ........
.......................
e poi
si definisca la funzione
levelOrder :: InfNBT → [Int]
che restituisce la lista delle etichette di un albero infinito ordinate livello per livello da sinistra
a destra.
Per esempio, la valutazione di (levelOrder myIT) produrra' la lista infinita
di tutti gli interi a partire da 1.
(Una possibile soluzione potrebbe utilizzare una funzione che, preso un albero ed un numero n,
restituisca la lista di tutti i sottoalberi di livello n)
Si scriva inoltre la piu' breve espressione Haskell il cui valore e' la lista
di tutti gli interi a partire da 1.
Possibile soluzione.
Esercizio 31
Esercizio 32
Scrivere un programma Haskell che riconosca o rifiuti stringhe appartenenti al linguaggio
regolare, sull'alfabeto {a,b,c}, associato alla seguente espressione regolare
abc*b + aa
Ricordiamo che il tipo String in Hakell coincide con [Char] e che un carattere si rappresenta tra
apici (es.: 'a').
Possibile soluzione.
Esercizio 33
La seguente funzione Erlang firstList2secondList
prende due liste non vuote di uguale lunghezza e restituisce una funzione che, preso un elemento
della prima lista restituisce l'elemento della seconda lista nella stessa posizione.
In Erlang la funzione predefinita lists:nth(N,L)
restituisce l'N-esimo elemento della lista L. Inoltre la funzione position
prende un elemento ed una lista che lo contiene e restituisce la sua posizione.
Notare inoltre l'uso di "fun" per denotare una funzione anonima.
firstList2secondlist(First,Second) ->
fun(Elem) -> N = position(Elem,First);
lists:nth(N,Second)
end.
Scrivere la stessa funzione in Haskell, senza utilizzare
funzioni ausiliarie come position e lists:nth.
Fornire il tipo principale calcolato da Haskell per la funzione definita.
Come mai in Haskell e' possibile fornire la funzione richiesta
in modo semplice ed elegante, mentre in Erlang cio' risulterebbe
piu' complesso?
Possibile soluzione.
Esercizio 34
Si consideri il seguente codice Haskell incompleto
data ......
treeapply f (Leaf x) = x
treeapply f (Node n t1 t2) = f n (treeapply f t1) (treeapply f t2)
e si completi con la definizione del tipo di dato in modo che questa
risulti la piu' generale possibile.
Cosa calcola la funzione treeapply?
Cosa restituisce l'interprete se chiediamo la cosa seguente?
:type treeapply
Giustificare la risposta.
Possibile soluzione.
Esercizio 35
Esercizio 36
Esercizio XX
Possibile soluzione.