Herramientas de usuario

Herramientas del sitio


introalg:taller2

Clase 2

Plan para hoy

  • Repaso de algunas soluciones de la clase anterior.
  • Sintáxis de pattern matching.
  • Trabajar sobre programas recursivos numéricos y con listas.
  • 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 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?. 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 basan 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 '4'.

El mecanismo básico para poder destruir una lista en partes es el pattern matching, que podemos pensarlo como una definición por casos, que 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.

cola :: [a] -> [a]
cola (x:xs) = xs

También tenemos pattern matching numérico.
Vemos como escribir una funcion que devuelve verdadero si y solo 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

Programas Recursivos

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, siendo el primero x y el resto de la lista xs)
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 olvidamos duplicar la “cola” de la lista.
Lo arreglamos rápidamente, aplicando la misma definición de duplicar a la lista restante.

Veamos ahora el ejercicio 12.

Defina la función sumatoria:[Num]->Num que dada una lista devuelve la suma de sus elementos.

La estrategia es la misma que en el caso anterior

  • Definir caso base para la lista vacía.
  • Definir el caso inductivo para la lista con al menos un elemento, suponiendo que ya esta definido para longitudes menores.
sumatoria :: [Int] -> Int
sumatoria [] = 0
sumatoria (x:xs) = x + sumatoria xs

Vemos algunos ejemplos

Main> sumatoria [1,2,3]
6
Main> sumatoria (duplicar (duplicar [1,2,3]))
24
Main> sumatoria ((duplicar.duplicar) [1,2,3])
24

Veamos el siguiente código y tratemos de entender que es lo que computa

desdeHasta :: Int -> Int -> [Int]
desdeHasta n m  | n>m  = []
                | n==m = [n]
                | n<m  = n : desdeHasta (n+1) m
  • ¿A qué evaluaría desdeHasta 10 10?
  • ¿Y desdeHasta 4 1?
  • Finalmente que pasa exactamente con desdeHasta 41 43.

Notamos que son importantes

  • Los nombres de la función y de las variables, pues ayudan a entender su funcionalidad.
  • La signatura o declaración de los tipos.
  • Una buena diagramación de los casos.

Ejercicios

Realizar en lo que resta de la clase

  • (P8-E11) 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 duplicar.
  • (P8-E12) Defina la función promedio promedio:[Num] → Num que dada una lista de números, calcule su promedio.
  • (P8-E16) (*) c) Modificar la guarda de n>m en desdeHasta para que si esto pasa retorne la lista descendente.
introalg/taller2.txt · Última modificación: 2018/08/10 03:03 por 127.0.0.1