¡Esta es una revisión vieja del documento!
Tabla de Contenidos
Clase 2
Plan para hoy
- Repaso de algunas soluciones de la clase anterior
- Trabajar sobre programas recursivos numéricos y con listas
- Sintáxis de pattern matching
- Resolución de ejercicios
Algunas soluciones de la clase anterior
Veamos algunas soluciones presentadas Wiki de Scripts Haskell.
Notamos
- No hay una única forma de resolver un problema.
- Como podemos hacer control de los parámetros de entrada.
- Cláusula
otherwise
para análisis por casos. - Comentarios en el código.
- Uso del
if-then-else
en vez de análisis por casos. - ¿Guardas exhaustivas? y uso del cálculo proposicional.
- No se usaron definiciones locales para la función de cálculo de área.
Se aprende muchísimo leyendo detenidamente código bien escrito.
Clase
Hasta ahora vimos programas funcionales no recursivos, que se basaban en la composición de funciones de la bibilioteca (prelude
) y las definidas en Scripts de Haskell.
Veamos la última función no recursiva que vamos a plantear, que sirve para presentar el mecanismo de pattern matching.
Ejercicio 8 Definir la función cabeza:[A]->A que devuelve el primer elemento de la lista.
Por ejemplo cabeza [4,3,2]
reduce a la forma canónica '2'.
El mecanismo básico para poder destruir una lista en partes es el pattern matching, que es una especie de definición por casos que a su vez es capaz de dividir la lista en su cabeza y cola
cabeza :: [a] -> a cabeza (x:xs) = x
Podemos agregar esta definición a un script de Haskell con nombre practico8.hs
.
Evaluemos algunos casos.
Main> cabeza [1,2,3] 1 Main> cabeza "minombre" 'm' Main> cabeza [] Program error: pattern match failure: cabeza []
De la misma forma podemos hacer la función cola
solo que devolviendo xs
en lugar de x.
También tenemos pattern matching numérico. Vemos como escribir una funcion que devuelve verdadero si el número es 0 o 1 (puede ser útil para el ejercicio 17)
ceroOuno :: Int -> Bool ceroOuno 0 = True ceroOuno 1 = True ceroOuno x = False
Ahora tomemos el ejercicio 10 del Práctico 8
Defina la función duplicar::[Num]->[Num] que dada una lista duplica cada uno de sus elementos. Ejemplo: duplicar [2,4,8] = [4,8,16]
Usamos un planteamiento inductivo o recursivo y pattern matching para
- Definir un caso base (lista vacía)
- Definir el caso inductivo (la lista tiene al menos un elemento)
duplicar :: [Int] -> [Int] duplicar [] = [] -- caso base duplicar (x:xs) = 2*x : xs -- caso inductivo
Probamos la definición
Main> duplicar [2,3,4] [4,3,4]
¿Donde está el error?
Simplemente la “cola” de la lista no sufrió modificación. Lo arreglamos rápidamente, aplicando la misma definición de duplicar a la lista restante.
Ejercicios
Realizar en lo que resta de la clase
- (P8-E1) Definir la función multiplicar:[Num]→ Num → [Num] que dada una lista y un número r multiplica cada uno de los elementos por r. Ejemplo multiplicar.[2,4,8].3 = [6,12,24]. Notar que generaliza duplica.