Pages: 1 [2]   Go Down
Print
Author Topic: Aiuto esercizio Haskell  (Read 5252 times)
0 Members e 1 Utente non registrato stanno visualizzando questa discussione.
Acicatena86
Apprendista Forumista
**
Offline Offline

Gender: Male
Posts: 404


See full me now who neon


« Reply #15 on: 09-04-2013, 20:14:56 »

Buonasera professore, ho provato ad implementare in Haskell l'esercizio in scheme della lista di due liste...

Quote
Una funzione (Scheme per ora) che prende una lista e un predicato
e restituisce una lista di due liste, in cui la prima sono gli elementi
che soddisfano il predicato e la seconda gli altri.


Ecco la mia soluzione

Code:
funSplit [] p=([],[])

funSplit (xs) p=([y| y<-xs, (p y)],[x | x<-xs, not(p x)])


Va bene, ma per farlo usando lo stesso algoritmo che abbiamo utilizzato per implementare questa
funzione in Scheme, occorre non usare funzioni ausiliare (la list comprehension e' come una funzione
ausiliaria).

FB

Professore,così va bene invece?

funSplit [] p=([],[])

funSplit (x:xs) p
                  |(even x) =(x:first,second)
                  |otherwise =(first,x:second)
                  where (first,second)=funSplit xs p
Logged
Franco Barbanera
Moderator
Forumista Eroico
*****
Offline Offline

Posts: 3.072



WWW
« Reply #16 on: 10-04-2013, 13:45:53 »


Professore,così va bene invece?

funSplit [] p=([],[])

funSplit (x:xs) p
                  |(even x) =(x:first,second)
                  |otherwise =(first,x:second)
                  where (first,second)=funSplit xs p

Great!

FB
Logged
Joe
Apprendista Forumista
**
Offline Offline

Posts: 492


« Reply #17 on: 11-04-2013, 18:16:21 »

Prof. sto svolgendo il punto 3 dell'esercizio 13, quello che chiede:

"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)"

Ho iniziato così:

Code:
data Abn = ENBT | MkAbn Int Abn Abn
data Abf = EFBT | MkAbf (Int -> Int) Abf Abf

appT :: Abf -> Abn -> (Maybe Abn)



Può suggerirmi come definire la funzione?

Se al secondo punto era così definita
Code:
appT :: Abf -> Abn -> Abn

appT EFBT ENBT = ENBT
appT (MkAbf f t1 t2) (MkAbn n t3 t4) = (MkAbn (f n) (appT t1 t3) (appT t2 t4))

Adesso come diventa tramite Maybe?
Logged
Franco Barbanera
Moderator
Forumista Eroico
*****
Offline Offline

Posts: 3.072



WWW
« Reply #18 on: 11-04-2013, 18:33:51 »

Intanto devi aggiungere una o piu' nuove equazioni alla definizione del programma (quella in cui prendi
in considerazione appunto il caso di alberi con struttura diversa.

E poi devi fare in modo che il risultato delle due equazioni gia' presenti dia un Maybe albero e non semplicemente
un albero.
Prova e fammi sapere.

FB
Logged
Joe
Apprendista Forumista
**
Offline Offline

Posts: 492


« Reply #19 on: 11-04-2013, 19:43:42 »

Intanto devi aggiungere una o piu' nuove equazioni alla definizione del programma (quella in cui prendi
in considerazione appunto il caso di alberi con struttura diversa.

E poi devi fare in modo che il risultato delle due equazioni gia' presenti dia un Maybe albero e non semplicemente
un albero.
Prova e fammi sapere.

FB

Ecco la mia soluzione:

Code:
data Abn = ENBT | MkAbn Int Abn Abn
data Abf = EFBT | MkAbf (Int -> Int) Abf Abf
appT :: Abf -> Abn -> (Maybe Abn)

appT EFBT ENBT = (Just ENBT)
appT (MkAbf f t1 t2) (MkAbn n t3 t4) = do tree1 <- appT t1 t3
                                                                tree2 <- appT t2 t4
                                                                Just (MkAbn (f n) tree1 tree2)
Logged
Franco Barbanera
Moderator
Forumista Eroico
*****
Offline Offline

Posts: 3.072



WWW
« Reply #20 on: 12-04-2013, 08:15:30 »

Bene.

Pero' manca l'equazione piu' importante, quella che giustifica l'uso nel nostro caso
della monade Maybe: vogliamo che applicando la funzione a due alberi con struttura diversa
si produca il valore indeterminato.


P.S. certo che quando vedete qualcosa che odora anche falsamente di imperativo
vi ci buttate a pesce, eh?  (intendo l'espressione do per un uso piu' intuitivo dell'operatore >>= )
:-)



 
Logged
Joe
Apprendista Forumista
**
Offline Offline

Posts: 492


« Reply #21 on: 12-04-2013, 10:59:17 »

Bene.

Pero' manca l'equazione piu' importante, quella che giustifica l'uso nel nostro caso
della monade Maybe: vogliamo che applicando la funzione a due alberi con struttura diversa
si produca il valore indeterminato.


P.S. certo che quando vedete qualcosa che odora anche falsamente di imperativo
vi ci buttate a pesce, eh?  (intendo l'espressione do per un uso piu' intuitivo dell'operatore >>= )
:-)



 

Code:
data Abn = ENBT | MkAbn Int Abn Abn
data Abf = EFBT | MkAbf (Int -> Int) Abf Abf

appT :: Abf -> Abn -> (Maybe Abn)

appT EFBT ENBT = (Just ENBT)
appT (MkAbf f t1 t2) (MkAbn n t3 t4) = (appT t1 t3) >>=
                                        \tree1 -> (appT t2 t4) >>=
                                        \tree2 -> Just (MkAbn (f n) tree1 tree2)
                                           
appT _ _ = Nothing
Logged
Acicatena86
Apprendista Forumista
**
Offline Offline

Gender: Male
Posts: 404


See full me now who neon


« Reply #22 on: 13-04-2013, 13:58:20 »

Esercizio 14
Code:
definire in Haskell il tipo di dato Lambda-Termine e realizzare le funzioni fv e bv che calcolano gli insiemi delle variabili, rispettivamente, libere e legate di un termine.
Per realizzare fv e bv si utilizzi il dato

data Set a = Set [a]

Ecco la mia soluzione

Code:
data Set a=Set [a]
           deriving(Show)
          

data Var= Var Int
            deriving(Show)

instance Eq Var where
   (Var a)==(Var b)= (a==b)
   _ == _ =False
  

data LambdaTermine= LambdaVar Var| App LambdaTermine LambdaTermine| Lambda Var LambdaTermine
                    deriving(Show)
union (Set s1)(Set s2)= Set([y | y<-s1, not(elem y s2)]++s2)
 
minus (Set s1)(Set s2)=Set ([y |y<-s1, not (elem y s2)])


bv:: LambdaTermine->(Set SVar)


bv (LambdaVar x)=(Set[])
bv(App m n)=union (bv m) (bv n)
bv (Lambda x m)=union (Set [x]) (bv m)




fv (LambdaVar x)=(Set [x])
fv (App m n)=union (fv m) (fv n)
fv(Lambda x m)=minus (fv m) (Set [x])

Logged
Franco Barbanera
Moderator
Forumista Eroico
*****
Offline Offline

Posts: 3.072



WWW
« Reply #23 on: 14-04-2013, 12:02:21 »

Pare giusta e ben fatta.

FB
Logged
Franco Barbanera
Moderator
Forumista Eroico
*****
Offline Offline

Posts: 3.072



WWW
« Reply #24 on: 15-04-2013, 14:56:41 »

Esercizio 14
Code:
definire in Haskell il tipo di dato Lambda-Termine e realizzare le funzioni fv e bv che calcolano gli insiemi delle variabili, rispettivamente, libere e legate di un termine.
Per realizzare fv e bv si utilizzi il dato

data Set a = Set [a]

Ecco la mia soluzione

Code:
data Set a=Set [a]
           deriving(Show)
          

data Var= Var Int
            deriving(Show)

instance Eq Var where
   (Var a)==(Var b)= (a==b)
   _ == _ =False
  

data LambdaTermine= LambdaVar Var| App LambdaTermine LambdaTermine| Lambda Var LambdaTermine
                    deriving(Show)
union (Set s1)(Set s2)= Set([y | y<-s1, not(elem y s2)]++s2)
 
minus (Set s1)(Set s2)=Set ([y |y<-s1, not (elem y s2)])


bv:: LambdaTermine->(Set SVar)


bv (LambdaVar x)=(Set[])
bv(App m n)=union (bv m) (bv n)
bv (Lambda x m)=union (Set [x]) (bv m)




fv (LambdaVar x)=(Set [x])
fv (App m n)=union (fv m) (fv n)
fv(Lambda x m)=minus (fv m) (Set [x])

Sarebbe carino implementare la funzione show per il tipo lambda termine,
magari facendo rispettare le convenzioni sulle parentesi.

Salutoni
FB
Logged
Acicatena86
Apprendista Forumista
**
Offline Offline

Gender: Male
Posts: 404


See full me now who neon


« Reply #25 on: 09-05-2013, 20:18:19 »

Salve Professore, ho svolto l'esercizio 23 sulla Programmazione Haskell

"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."


Ecco la mia soluzione


data A =MkI Int | MkB Bool
  deriving(Show)

data ListAlternate = Mk [A]

getValueAI (MkI n)=n
getValueAB (MkB bool)=bool

divide []=([],[])

divide (x:y:xs)= (getValueAI(x):first,getValueAB(y):second)
                where(first,second)=divide(xs)


Valore di prova


myAlternate=[MkI 3, MkB True, MkI 6,MkB False,MkI 5,MkB True]
divide (myAlternate)
OUTPUT
([3,6,5],[True,False,True])


E' corretto? (Dovrei gestire pure il caso in cui il numero di Int sia diverso da quello dei Bool? )
Logged
Franco Barbanera
Moderator
Forumista Eroico
*****
Offline Offline

Posts: 3.072



WWW
« Reply #26 on: 10-05-2013, 10:43:47 »

Scorretto.
In questo modo hai definito il tipo di dato lista con elementi bool o int.
In questo modo tu hai il seguente elemento di tipo ListAlternate:
Mk [MkI 3, MkI 5, MkBB]

e' una lista con due int ed un bool che pero' non sono alternati.....


Salutoni
FB
Logged
Franco Barbanera
Moderator
Forumista Eroico
*****
Offline Offline

Posts: 3.072



WWW
« Reply #27 on: 17-05-2013, 17:21:36 »

L'unica soluzione con un minimo di eleganza e' la seguente, che pero' ha il difetto che
le liste iniziano sempre con elementi di uno dei due tipi:

data AltList a b = EmptyAL | ConsAL a (AltList b a)

Per esempio, nelle liste di tipo (ALtList Integer Bool) gli interi e i booleani sono sempre alternati,
ma la lista inizia necessariamente sempre con un intero.
Non credo che si riesca a fare qualcosa di altrettanto elegante senza avere questo vincolo
(nel caso, fatemi sapere).

La funzione divide si definisce in questo caso nel seguente modo:

divide:: (AltList Integer Bool) -> ([Integer],[Bool])

divide EmptyAL = ([],[])

divide (ConsAL n EmptyAL) = ([n],[])

divide (ConsAL n (ConsAL b als)) = (n:ints,b:bools)
                                   where (ints,bools) = divide als



-- esempio di lista
myAL = ConsAL 3 (ConsAL True (ConsAL 5 (ConsAL False (ConsAL 1 (ConsAL False EmptyAL)))))



FB
Logged
Pages: 1 [2]   Go Up
Print
Jump to: