-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathColaConListas.hs
124 lines (105 loc) · 3.26 KB
/
ColaConListas.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
-- ColaConListas.hs
-- Implementación de las colas mediante listas.
-- José A. Alonso Jiménez <https://jaalonso.github.io>
-- Sevilla, 20-enero-2023
-- ---------------------------------------------------------------------
{-# LANGUAGE FlexibleInstances #-}
{-# OPTIONS_GHC -fno-warn-unused-top-binds #-}
module TAD.ColaConListas
(Cola,
vacia, -- Cola a
inserta, -- a -> Cola a -> Cola a
primero, -- Cola a -> a
resto, -- Cola a -> Cola a
esVacia, -- Cola a -> Bool
) where
import Test.QuickCheck
-- Colas como listas:
newtype Cola a = C [a]
deriving Eq
-- (escribeCola c) es la cadena correspondiente a la cola c. Por
-- ejemplo,
-- escribeCola (inserta 5 (inserta 2 (inserta 3 vacia))) == "3 | 2 | 5"
escribeCola :: Show a => Cola a -> String
escribeCola (C []) = "-"
escribeCola (C [x]) = show x
escribeCola (C (x:xs)) = show x ++ " | " ++ escribeCola (C xs)
-- Procedimiento de escritura de colas.
instance Show a => Show (Cola a) where
show = escribeCola
-- Ejemplo de cola:
-- λ> inserta 5 (inserta 2 (inserta 3 vacia))
-- 3 | 2 | 5
-- vacia es la cola vacía. Por ejemplo,
-- λ> vacia
-- -
vacia :: Cola a
vacia = C []
-- (inserta x c) es la cola obtenida añadiendo x al final de la cola
-- c. Por ejemplo,
-- λ> ej = inserta 2 (inserta 3 vacia)
-- λ> ej
-- 3 | 2
-- λ> inserta 5 ej
-- 3 | 2 | 5
inserta :: a -> Cola a -> Cola a
inserta x (C c) = C (c ++ [x])
-- (primero c) es el primer elemento de la cola c. Por ejemplo,
-- λ> primero (inserta 5 (inserta 2 (inserta 3 vacia)))
-- 3
primero :: Cola a -> a
primero (C []) = error "primero: cola vacia"
primero (C (x:_)) = x
-- (resto c) es la cola obtenida eliminando el primer elemento de la
-- cola c. Por ejemplo,
-- λ> resto (inserta 5 (inserta 2 (inserta 3 vacia)))
-- 2 | 5
resto :: Cola a -> Cola a
resto (C (_:xs)) = C xs
resto (C []) = error "resto: cola vacia"
-- (esVacia c) se verifica si c es la cola vacía. Por ejemplo,
-- esVacia (inserta 5 (inserta 2 (inserta 3 vacia))) == False
-- esVacia vacia == True
esVacia :: Cola a -> Bool
esVacia (C xs) = null xs
-- Generador de colas
-- ==================
-- genCola es un generador de colas de enteros. Por ejemplo,
-- λ> sample genCola
-- -
-- -
-- -3 | 2
-- 6 | 0 | 1
-- -5 | 0 | -5 | 0 | -4
-- 2 | 9 | -6 | 9 | 0 | -1
-- -
-- 11 | -5 | 5
-- -
-- 16 | 6 | 15 | -3 | -9
-- 11 | 6 | 15 | 13 | 20 | -7 | 11 | -5 | 13
genCola :: (Arbitrary a, Num a) => Gen (Cola a)
genCola = do
xs <- listOf arbitrary
return (foldr inserta vacia xs)
-- El tipo cola es una instancia del arbitrario.
instance (Arbitrary a, Num a) => Arbitrary (Cola a) where
arbitrary = genCola
-- Propiedades de las colas
-- ========================
-- Las propiedades son
prop_colas1 :: Int -> Cola Int -> Bool
prop_colas1 x c =
primero (inserta x vacia) == x &&
resto (inserta x vacia) == vacia &&
esVacia vacia &&
not (esVacia (inserta x c))
prop_colas2 :: Int -> Cola Int -> Property
prop_colas2 x c =
not (esVacia c) ==>
primero (inserta x c) == primero c &&
resto (inserta x c) == inserta x (resto c)
-- La comprobación es:
-- λ> quickCheck prop_colas1
-- +++ OK, passed 100 tests.
-- λ> quickCheck prop_colas2
-- +++ OK, passed 100 tests; 3 discarded.