Tipos Algebraicos Taller de Álgebra I Primer cuatrimestre de 2015 Recordemos algunos tipos que fuimos creando en clases anteriores ¿Cuál es la diferencia entre type y data? Tipos Enumerados usando data. data Dia = Lunes | Martes | Miercoles | ... | Sabado | Domingo También algunos renombres de tipos con type. data Direccion = Norte | Sur | Este | Oeste deriving Show type Tortuga = ( Pos , Direccion ) type Pos = ( Int , Int ) Luego de definirlos, podemos decir que: Norte :: Direccion ((1 ,1) , Sur ) :: Tortuga -- Si f :: Dia -> Bool f Martes :: Bool -- Si t :: Tortuga fst t :: Pos Recordemos el tipo que creamos en la clase anterior Tipos Paramétricos los constructores toman parámetros data Figura = Rectangulo Punto Punto | Circulo Punto Float | Triangulo Punto Punto Punto deriving ( Eq , Show ) type Punto = ( Float , Float ) Podemos decir que: Rectangulo (0.3 , 0.5) :: Figura Circulo (0 ,0+20.23) 88.3 :: Figura -- Si area :: Figura -> Float area ( Triangulo (0 ,0) (1 ,0) (0 ,1) ) :: Float Ahora se pone jevy.. Tipos Algebraicos Recursivos algunos constructores toman parámetros y estos a su vez son del tipo que se está definiendo Ejemplo: Árboles Estrictamente Binarios de Enteros Un árbol estrictamente binario de enteros es una estructura muy utilizada en computación y matemática. Veamos cómo podemos representarlos: data ABE = ArbVacio | Binario ABE Integer ABE deriving ( Eq , Show ) En este caso, ArbVacio es un constructor que no toma parámetros y Binario es un constructor que toma 3 parámetros, de los cuales 2 son el tipo que se está definiendo. Ejercicios Determinar el tipo y dibujar una representación (en papel y sólo si es posible) de las siguientes expresiones: ArbVacio (ArbVacio, 20.23) Binario ArbVacio 10 ArbVacio [Binario ArbVacio 5 (Binario ArbVacio 10 ArbVacio), ArbVacio] Binario ArbVacio 5 (Binario ArbVacio) Más sobre los Árboles Árboles Estrictamente Binarios de Enteros data ABE = ArbVacio | Binario ABE Integer ABE Si lo necesitan, puede agregarse deriving (Eq, Show) al final de la definición. Ejercicios Implementar las siguientes funciones: esVacio :: ABE -> Bool que determina si un árbol tiene o no nodos. sumaNodos :: ABE -> Integer que devuelve la suma de los nodos del árbol. altura :: ABE -> Integer que devuelve la altura de un árbol. pertenece :: Integer -> ABE -> Bool que indica si un elemento pertenece o no a un árbol. busqueda :: [Bool] -> ABE -> Integer que recorre el árbol siguiendo la lista de instrucciones (True significa derecha, False significa izquierda) y devuelve el valor que se encuentre luego de recorrerlo (asumir que la lista lleva a un elemento y no se termina el árbol antes de encontrarlo) Todo muy lindo.. peeero ¿Y si quisiera que mis arboles contengan Char? Árboles Estrictamente Binarios de Chars data ABC = ArbVacioC | BinarioC ABC Char ABC Ahora quiero uno de tuplas de la pinta (Integer, Float) Árboles Estrictamente Binarios de Tuplas (Integer, Float) data ABTIF = ArbVacioTIF | BinarioTIF ABTIF ( Integer , Float ) ABTIF Notar que necesitamos nombres distintos para los constructores para saber a qué tipo pertenecen. ¿Se podrá generalizar este comportamiento? Tipos Genéricos ¿qué tal si usamos tipos genéricos? data AB t = Nil | Bin ( AB t ) t ( AB t ) Estamos definiendo infinitos tipos (uno por cada tipo t que haya) Ejemplos Nil :: AB t Bin Nil 2 Nil :: AB Integer Bin Nil ’a’ Nil :: AB Char Bin Nil "Álgebra" Nil :: AB String Bin (Bin Nil 2 Nil) 6 Nil :: AB Integer Bin Nil (Bin Nil 2 Nil) Nil :: AB (AB Integer) Tipos Genéricos Árboles Binarios Genéricos data AB t = Nil | Bin ( AB t ) t ( AB t ) Ejercicios: implementar las siguientes funciones vacio :: AB a -> Bool que determina si el árbol está vacio. maximo :: Num a => AB a -> a que devuelve el máximo elemento de un árbol de números no vacio. todosIguales :: Eq t => AB t -> Bool que determina si todos los nodos del árbol tienen el mismo valor entre sı́. Ejercicios 1 definir esHeap :: Num a => AB a -> Bool que vale verdadera en un árbol si cada nodo (salvo la raı́z) es mayor o igual que su padre. 2 Dado el siguiente tipo algebraico, implementar las funciones: data Lista a = Vacia | Agregar a ( Lista a ) 1 2 3 4 5 vacia :: Lista a -> Bool que determina si una lista es o no la lista vacia. suma :: Lista Float -> Float que determina la suma de una lista de floats. enPosicion :: Lista a -> Integer -> a que devuelve el elemento en la posición pasado como parámetro. (*) iguales :: Eq a => Lista a -> Lista a -> Bool que determina si dos listas de elementos (comparables por igual) son iguales. juntar :: Lista a -> Lista b -> Lista (a,b) que crea una lista resultante de formar tuplas con los elementos de cada lista. Se asume que las dos listas tienen la misma longitud. Por ejemplo: juntar (Agregar 1 (Agregar 2 Vacia)) (Agregar ’a’ (Agregar ’b’ Vacia)) Agregar (1, ’a’) (Agregar (2, ’b’) Vacia)