-
Notifications
You must be signed in to change notification settings - Fork 23
/
examen.hs
81 lines (68 loc) · 2.1 KB
/
examen.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
-- Definiția tipului arbore
data Arb = Leaf Integer | Node Arb Arb Arb
-- O direcție pe care o pot lua când parcurg arborele
data Direction = L | M | R
deriving (Eq, Show)
-- O listă de direcții care duc la o frunză
type LeafCode = [Direction]
-- Monada Writer
data Writer a = Writer
{ output :: [LeafCode],
value :: a
}
-- Derivez clasa de tipuri
instance Monad Writer where
return x = Writer { output = [], value = x }
w >>= k =
let
Writer out1 v1 = w
Writer out2 v2 = k v1
in
Writer (out1 ++ out2) v2
instance Functor Writer where
fmap f w = do f <$> w
instance Applicative Writer where
pure = return
fw <*> w = do
f <- fw
f <$> w
-- Funcție ajutătoare care scrie un drum în output
write :: LeafCode -> Writer ()
write code = Writer [code] ()
-- Funcție ajutătoare care primește drumul curent
leafCodes' :: Arb -> Integer -> LeafCode -> Writer ()
-- Cazul frunză: verific dacă frunza are valoarea cerută,
-- și o afișez.
leafCodes' (Leaf v) i code =
if v == i then
write code
else
return ()
-- Cazul nod: verific recursiv fiecare sub-arbore.
leafCodes' (Node left middle right) value code = do
leafCodes' left value (code ++ [L])
leafCodes' middle value (code ++ [M])
leafCodes' right value (code ++ [R])
leafCodes :: Arb -> Integer -> Writer ()
leafCodes arb value = leafCodes' arb value []
---- Teste ----
-- Exemplul din cerință
tree :: Arb
tree = Node
(Node (Leaf 1) (Leaf 3) (Leaf 4))
(Node (Leaf 1) (Leaf 2) (Leaf 4))
(Leaf 4)
t1 :: Bool
t1 = output (leafCodes tree 4) == [[L, R], [M, R], [R]]
-- Când nu găsește nimic, trebuie să returneze lista vidă
t2 :: Bool
t2 = output (leafCodes tree (-1)) == []
-- Când îi dau doar o frunză și aceasta se potrivește,
-- returnează o listă care conține lista vidă
-- (deci un singur drum, de lungime 0).
t3 :: Bool
t3 = output (leafCodes (Leaf 1) 1) == [[]]
-- Când îi dau doar o frunză și aceasta nu se potrivește,
-- returnează lista vidă (nu există drumuri).
t4 :: Bool
t4 = output (leafCodes (Leaf 1) 2) == []