Programación Funcional Haskell Clase 21 José Raymundo Marcial Romero rmarcial@fi.uaemex.mx BUAP c José Raymundo Marcial Romero. Clase Número 21 p.1/12
Temas de la clase Clase Anterior En Haskell cada expresión bien formada tiene un tipo Tipos polimórficos y clases tipo Esta clase Tipos y clases preconstruidos en las librerías de Haskell Caracteres Listas c José Raymundo Marcial Romero. Clase Número 21 p.2/12
Caracteres Los caracteres (letras, dígitos y caracteres especiales) son el medio de comunicación entre las personas y las computadoras mediante teclados como entrada y pantallas como salida. Haskell tiene un tipo preconstruido para caracteres, llamado Char, el cual contiene 256 caracteres, los cuales se representan encerrandolos en comillas simples, por ejemplo: 7, b. Algunos caracteres especiales se representan de la siguiente manera: \ t (tab) \ n (Línea nueva) \\ (backslash) \ (comilla simple) \ (comilla doble) c José Raymundo Marcial Romero. Clase Número 21 p.3/12
Funciones del tipo Char El código ASCII sirve para representar los caracteres como enteros, por ejemplo, las letras mayusculas A a z tienen la secuencia de códigos desde 65 hasta 90. Note que el caracter con código 98 se puede escribir como \ 98 ( b y \ 98 tienen el mismo significado). Dos funciones primitivas para el manejo de caracteres son: ord :: Char -> Int chr :: Int -> Char Si se toma en cuenta ésta conversión, los caracteres pueden ser comparados y ordenados. La ordenación permite la definición de algunas funciones simples, como: isupper:: Char -> Bool isupper ch = A <= ch && ch <= Z c José Raymundo Marcial Romero. Clase Número 21 p.4/12
Listas (o secuencias) Una lista es una coleción de elementos linealmente ordenados, todos del mismo tipo, por ejemplo: [1, 2, 3, 34, 21, 150] :: [Int] [ h, e, l, l, o ] :: [Char] [[1, 2], [23], [456, 67, 200]] :: [[Int]] [(+), ( )] :: [Int > Int > Int] El tipo lista es un tipo de datos sumamente expresivo: un texto puede representarse como una lista de ĺıneas, cada una de las cuales es una lista de palabras; una colección de mediciones puede representarse como una lista de números de punto flotante. Las funciones recursivas se pueden definir sobre listas, usualmente por pattern matching. c José Raymundo Marcial Romero. Clase Número 21 p.5/12
Construcción de listas Un caso especial de lista es la lista vacía [], que no contiene elementos. La lista vacía es un elemento de cualquier lista, y esta definida para cada tipo de lista, es decir: [] :: [a] Una lista de caracteres es una cadena: [ h, e, l, l, o ] == hello Existen diferentes formas de construir una lista Comenzando con la lista vacía y agregandole elementos uno por uno, usando el operador (:) :: a-> [a] -> [a] [n..m] que significa [n, n + 1, n + 2,..., m] [n, p,..m] que significa la lista cuyos primeros dos elementos son n y p y cuyo último elemento es m, y los elementos restantes incrementando (decrementando) en p n pasos. Empleando una notación particular llamada list comprehesion (las listas que se escriben con esta notación también se conocen como expresiones ZF). c José Raymundo Marcial Romero. Clase Número 21 p.6/12
Empleando el operador (:) Ejemplos -1 [1,2,3] == 1: (2: (3:[])) = 1:2:3:[] 2:[8,13] == [2,8,13] h : "askell" == "haskell" Empleando la notación [n..m] [1.. 10] == [1,2,3,4,5,6,7,8,9,10] [ a.. f ] == "abcdef" [3.1.. 7.1] == [3.1, 4.1, 5.1, 6.1, 7.1] Empleando la notación [n, p..m] [3,5.. 13] == [3,5,7,9,11,13] [7,6.. 3] == [7,6,5,4,3] [ a, c,.. n ] == "acegikm" c José Raymundo Marcial Romero. Clase Número 21 p.7/12
Ejemplos-2 Empleando list comprehesion [2 n n [2, 4, 7]] == [4, 8, 14] esto se lee como: devuelve 2 n donde n proviene de [2,4,7] [x x x [1..5], even x] == [4, 16] esto se lee como: devuelve todos los x x donde x proviene de [1,2,3,4,5] y x es par. La forma general de una expresión ZF es: [< exp > < qual >,..., < qual >] donde < qual > es una expresión booleana o un generador. Un generador es algo de la forma: <variable> <- <list> <pattern> <- <list> c José Raymundo Marcial Romero. Clase Número 21 p.8/12
Nombres, cadenas y caracteres No confundir una, a y a a es un nombre o una variable; que puede tener un tipo a es un caracter y su tipo es Char a es una cadena y es de tipo [Char] No confundir apple y apple apple es un nombre o una variable, mientras que apple es una cadena. No confundir 9 y 9 9 es un número mientras que 9 es un caracter. c José Raymundo Marcial Romero. Clase Número 21 p.9/12
Funciones sobre listas head,last :: [a] > a El primer/último elemento de la lista, por ejemplo: head[7,18,3] == 7 last[7,18,3] == 3 tail,init :: [a] > [a] El complemento de primer/último tail[7,18,3] == [18,3] init[7,18,3] == [7,18] length :: [a] > Int La longitud de la lista, por ejemplo, length apple == 5 (!!) :: [a] > Int xs!!n regresa el nth elemento de xs, comenzando en el inicio y contando desde 0, por ejemplo [1,2,3,4]!!1 == 2 time!!2 == m (++) :: [a] > [a] > [a] Une dos listas, por ejemplo, c José Has Raymundo + Marcial + kell Romero. == Clase Haskell Número 21 p.10/12
attern matching en funciones recursivas Queremos definir una función sumlist tal que sumlist[1,2,3,4] == 1 + 2 + 3 + 4 == 10. Una solución utilizando equaciones guarded: sumlist xs xs == [] = 0 otherwise = head xs + sumlist (tail xs) solución empleando pattern matching: sumlist [] = 0 sumlist [x:xs] = x + sumlist xs c José Raymundo Marcial Romero. Clase Número 21 p.11/12
Como trabaja el pattern matching sumlist [] = 0 sumlist (x:xs) = x + sumlist xs sumlist [8,9] sumlist (8:9:[]) no empata con sumlist [] empata sumlist (x:xs) x=8 xs=(9:[]) así 8 + sumlist [9] 8 + sumlist (9:[]) no empata con sumlist [] empata con sumlist (x:xs) x =9 xs=[] así 8 + 9 + sumlist [] empata con sumlist [] así 8 + 9 + 0 = 17 c José Raymundo Marcial Romero. Clase Número 21 p.12/12