Herramientas de usuario

Herramientas del sitio


introalg:taller3

¡Esta es una revisión vieja del documento!


Clase 3

Plan para hoy

Algunas soluciones de la clase anterior

Veamos algunas soluciones presentadas Wiki de Scripts Haskell.

Clase

Veamos el ejercicio 18

Defina la función paraTodo: (A→ Bool)→ [A]→ Bool, donde paraTodo.p.xs decide si todos los elementos de la lista xs cumplen con el predicado p.

Nuevamente esta función es el típico caso que se resuelve con un caso base y un caso inductivo

paraTodo :: (a->Bool) -> [a] -> Bool
paraTodo p [] = True
paraTodo p (x:xs) = p x && paraTodo p xs

Notemos que esta función toma como parámetro una función.

  • Funciones que toman funciones.
  • Funciones de alto orden.

Esto es muy poderoso porque permite escribir programas funcionales que toman programas funcionales y generan otros programas funcionales.
Las funciones son ciudadanos de primera categoría no como en otros lenguajes de programación (imperativos).

Definimos rápidamente el predicado noMultiplo p n que indica cuando p no es múltiplo de n.

noMultiplo :: Int -> Int -> Bool
noMultiplo p n = p `mod` n >0

Notamos:

  • Volvimos infija la función mod.
  • Usamos una versión currificada.

Podríamos haber escrito

noMultiplo' :: (Int,Int) -> Bool
noMultiplo' (p,n) = p `mod` n >0

Sin embargo son diferentes pues noMultiplo permite la aplicación parcial

Main> :t noMultiplo
noMultiplo :: Int -> Int -> Bool
Main> :t noMultiplo 20
noMultiplo 21 :: Int -> Bool
Main> :t noMultiplo 21 2
noMultiplo 21 2 :: Bool

Con estos elementos y la función desdeHasta que ya figura en sus practico8.hs, podemos construir la función primo (ejercicio).

También podemos usar aplicación parcial en los operadores (+, ==, *) usando secciones de los operadores.
Por ejemplo ver que todos los elementos de una lista son 0 lo escribimos como

Main> paraTodo (==0) [0,0,0,0,0]
True
Main> paraTodo (==0) (desdeHasta 0 20)
False
Main> :t (==0)
flip (==) 0 :: Num a => a -> Bool


Veamos ahora una función que “cierra” dos listas en una sola conteniendo pares.
Por ejemplo:

Main> cierra ["Saturnino", "Tamburrini", "Berlin"] [9,8,3]
[("Saturnino",9),("Tamburrini",8),("Berlin",3)]

Esta función requiere inducción en dos listas al mismo tiempo, por lo tanto tenemos el pattern matching tendrá ahora 4 casos.

  • Caso(s) base(s)
  • Caso(s) inductivo(s)
cierra :: [a] -> [a] -> [(a,a)]
cierra [] [] = []
cierra (x:xs) [] = []
cierra [] (y:ys) = []
cierra (x:xs) (y:ys) = (x,y) : cierra xs ys

Entonces probemos:

Main> cierra ["Saturnino", "Tamburrini", "Berlin"] [9,8,3]
ERROR - Cannot infer instance
*** Instance   : Num [Char]
*** Expression : cierra ["Saturnino","Tamburrini","Berlin"] [9,8,3]

¿Cuál es el problema?
Tenemos un problema de tipos, el tipo de la función no es lo suficientemente general.
Lo corregimos para que sea cierra :: [a] → [b] → [(a,b)].

Usando las ideas de este ejemplo podemos resolver los ejercicios 21 y 22 del práctico 8.


Generalicemos las funciones duplicar y multiplicar que vimos anteriormente.

duplicar :: [Int] -> [Int]
duplicar [] = []
duplicar (x:xs) = x*2 : duplicar xs
multiplicar :: [Int] -> Int -> [Int]
multiplicar [] a = []
multiplicar (x:xs) a = x*a : multiplicar xs a

La estructura es la misma, estamos aplicando una función a cada elemento de la lista.
El ejercicio 24 dice

a) Defina la función //mapear:(A -> B) -> [A] -> [B]// que dadas una función //f// y una lista //xs//, aplica //f// a cada elemento de la lista.
Ejemplo: //mapear.primo.[1,2,3,4,5,6]=[false,true,true,false,true,false]//.

Ejercicios

  • (P8,E19) Usando paraTodo, desdeHasta y noMultiplo, defina la función primo.

Pruebe con los siguientes primos: 7, 73, 739, 7393, 73939, 739391, 7393913, 73939133, donde sus sucesores no lo son.

  • (P8,E21) Defina la función iguales :: Eq a ⇒ [a] → [a] → Bool que retorna true si las listas son iguales.
  • (P8,E24) Definla la función mapear :: (a→b) → [a] → [b], que dada una función f y una lista xs aplica f a cada elemento de la lista. Escriba duplicar' y multiplicar' utilizando mapear.
introalg/taller3.1147783740.txt.gz · Última modificación: 2018/08/10 03:03 (editor externo)