Herramientas de usuario

Herramientas del sitio


introalg:taller07_4

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anteriorRevisión previa
Próxima revisión
Revisión previa
introalg:taller07_4 [2007/05/14 17:50] nicolaswintroalg:taller07_4 [2018/08/10 03:03] (actual) – editor externo 127.0.0.1
Línea 1: Línea 1:
 ====== Clase 4 ====== ====== Clase 4 ======
 +
 +
  
  
Línea 5: Línea 7:
 ===== Aplicación parcial (secciones) ===== ===== Aplicación parcial (secciones) =====
  
-Tomemos la siguente función Haskell que es una ligera variación de la que se encuentra en el problemario //esMultiplo//.+Tomemos la siguente función Haskell que es una ligera variación de //esMultiplo// que está en el problemario.
  
 <code> <code>
Línea 17: Línea 19:
  
 Esto lo podemos leer como que //esDivisor// es una función que toma un entero y **devuelve una función** de tipo //Int->Bool//. Esto lo podemos leer como que //esDivisor// es una función que toma un entero y **devuelve una función** de tipo //Int->Bool//.
-Esto es lo mismo que pasa en los ejercicios 5f, 5g y 5i del Práctico 5. +Esto es lo mismo que pasa en los ejercicios 5f, 5g y 5i del Práctico 5, y muestra que una función es un ciudadano de primera categoría en Haskell, puede ser devuelto como resultado de una función y también veremos que puede ser un parámetro de entrada
-De hecho le podemos preguntar a Hugs por el tipo de+ 
 +Para ganar confianza podemos preguntar a Hugs por el tipo de la aplicación parcial.
  
   Main> :t esDivisor 2   Main> :t esDivisor 2
Línea 28: Línea 31:
 <code> <code>
 esPar :: Int -> Bool esPar :: Int -> Bool
-esPar = esDivisor 2+esPar = esDivisor 2 x
 </code> </code>
  
 La función devuelve //True// si y solo si el entero es divisible por 2! La función devuelve //True// si y solo si el entero es divisible por 2!
-Notamos que esta definición es idéntica a esta versión **con argumentos**.+Notamos que esta definición es idéntica a esta versión **sin argumentos** que utiliza el mecanismo de secciones
 <code> <code>
 esPar' :: Int -> Bool esPar' :: Int -> Bool
-esPar' = esDivisor 2 x+esPar' = esDivisor 2
 </code> </code>
  
-Esta forma de denotar funciones se denomina [[http://en.wikipedia.org/wiki/Currying|currificación]], en honor al lógico [[http://es.wikipedia.org/wiki/Haskell_Curry|Haskell Curry]] ((Si si, el lenguaje Haskell se llama así por Haskell Curry.)).+Esta forma de escribir funciones se denomina [[http://en.wikipedia.org/wiki/Currying|currificación]], en honor al lógico [[http://es.wikipedia.org/wiki/Haskell_Curry|Haskell Curry]] ((Si si, el lenguaje Haskell se llama así por Haskell Curry.)).
  
 Este mecanismo de aplicación parcial de argumentos resulta muy elegante para escribir funciones. Este mecanismo de aplicación parcial de argumentos resulta muy elegante para escribir funciones.
Línea 59: Línea 62:
   [True,False,True,False]   [True,False,True,False]
  
-Le tiene que quedar claro que esta es una forma **elegante** y **compacta** de definir nuevas funciones a partir de otras, pero no es imprescindible. Por ejemplo, para el tercer ejemplo podemos definir la función auxiliar+Tiene que quedar claro que esta es una forma **elegante** y **compacta** de definir nuevas funciones a partir de otras, pero no es imprescindible. Por ejemplo, para el tercer ejemplo podemos definir la función auxiliar
  
 <code> <code>
Línea 71: Línea 74:
   [False,False,False,False]   [False,False,False,False]
  
 +=== Ejercicio ===
 +
 +  * Utilizando aplicación parcial en //( /= )//, definir la función //noEsCero :: Int -> Bool// que decide si un entero //x// es distinto a 0.
  
 ===== Generalización de las funciones vistas (map, filter, fold) ===== ===== Generalización de las funciones vistas (map, filter, fold) =====
 +
 +
  
  
Línea 87: Línea 95:
  
 ?No estamos ya cansados de escribir siempre lo mismo? ?No estamos ya cansados de escribir siempre lo mismo?
-Veamos solo algunas de las funciones de //tipo aplicación//, son todas idénticas, salvo por la **operación o función** que se aplica a cada elemento.+Las funciones de //tipo aplicación//, son todas idénticas, salvo por la **operación o función** que se aplica a cada elemento.
  
 <code> <code>
Línea 96: Línea 104:
  
 <code> <code>
-veintePorCiento : [Float] -> [Float] +veintePorCiento :: [Float] -> [Float] 
 veintePorCiento []     = [] veintePorCiento []     = []
 veintePorCiento (x:xs) = 0.2*x : veintePorCiento xs veintePorCiento (x:xs) = 0.2*x : veintePorCiento xs
Línea 118: Línea 126:
 Entonces **generalizemos** definiendo una función que toma como primer argumento la función que se aplicará a cada elemento de la lista. Entonces **generalizemos** definiendo una función que toma como primer argumento la función que se aplicará a cada elemento de la lista.
  
-Esta función es la primera que crearemos donde utilizamos **alto orden**, un nombre muy pomposo para algo bastante natural: **las funciones son un tipo más que puede ser tomado como parámetro y devuelto como resultado**.+Vemos nuevamente la aplicación del **alto orden**, un nombre muy pomposo para algo bastante natural: **las funciones son un tipo más que puede ser tomado como parámetro y devuelto como resultado**.
  
-Se dice que en Haskell las funciones son //ciudadanos de primera categoría//.+De nuevo, se dice que en Haskell las funciones son //ciudadanos de primera categoría//.
 Esto no ocurre en la mayoría de los //lenguajes imperativos// como C, C++, Pascal, Basic, etc. . Esto no ocurre en la mayoría de los //lenguajes imperativos// como C, C++, Pascal, Basic, etc. .
  
Línea 131: Línea 139:
 === Ejercicio === === Ejercicio ===
  
-  * Definir la función //mapNumero.f.xs//, //mapNumero : (Int -> Int) -> [Int] -> [Int]// que dada una función //f// y una lista de enteros //xs//, les aplica una función aritmética //f// y concatena el resultado en una lista. Ejemplo: //mapNumero.(+2).[0,1,2,3] = [2,3,4,5]//.+  * Definir la función //mapNumeros.f.xs//, //mapNumeros : (Int -> Int) -> [Int] -> [Int]// que dada una función //f// y una lista de enteros //xs//, les aplica una función aritmética //f// y concatena el resultado en una lista. Ejemplo: //mapNumeros.(+2).[0,1,2,3] = [2,3,4,5]//.
  
   probar con mapNumeros.(*2).[0,1,2,3], mapNumeros.absoluto.[-10,0,10].   probar con mapNumeros.(*2).[0,1,2,3], mapNumeros.absoluto.[-10,0,10].
 +
  
  
Línea 143: Línea 152:
 <code> <code>
 esPar :: Int -> Bool esPar :: Int -> Bool
-esPar x `mod` == 0+esPar = esDivisor 2
  
 soloPares :: [Int] -> [Int] soloPares :: [Int] -> [Int]
Línea 168: Línea 177:
  
   probar con filtraNumeros.entre0y9.[], filtraNumeros.entre0y9.[10,20,30].   probar con filtraNumeros.entre0y9.[], filtraNumeros.entre0y9.[10,20,30].
 +
 +
  
  
Línea 187: Línea 198:
  
 productoria :: [Int] -> Int productoria :: [Int] -> Int
-productoria []     0+productoria []     1
 productoria (x:xs) = producto x (productoria xs) productoria (x:xs) = producto x (productoria xs)
 </code> </code>
Línea 195: Línea 206:
 concatenaInt :: [[Int]] -> [Int] concatenaInt :: [[Int]] -> [Int]
 concatenaInt []       = [] concatenaInt []       = []
-concatenaInt (xs:xss) = xs ++ concatenaInt xss+concatenaInt (xs:xss) = (++) xs (concatenaInt xss)
 </code> </code>
  
Línea 229: Línea 240:
  
 <code> <code>
-mapa : (a -> b) -> [a] -> [b]+mapa :: (a -> b) -> [a] -> [b]
 mapa f []     = mapa f []     =
 mapa f (x:xs) = mapa f (x:xs) =
Línea 251: Línea 262:
 filtro p (x:xs) = filtro p (x:xs) =
 </code> </code>
 +
  
  
Línea 271: Línea 283:
  
 <code> <code>
-ceroUnoyAnteriores :: Int -> Bool -> Bool +ceroUnoYAnteriores :: Int -> Bool -> Bool 
-ceroUnoyAnteriores x b = (x==0 || x==1) && b+ceroUnoYAnteriores x b = (x==0 || x==1) && b
  
 todos0y1' :: [Int] -> Bool todos0y1' :: [Int] -> Bool
 todos0y1' []     = True todos0y1' []     = True
-todos0y1' (x:xs) = ceroUnoyAnteriores x (todos0y1' xs)+todos0y1' (x:xs) = ceroUnoYAnteriores x (todos0y1' xs)
 </code> </code>
  
Línea 294: Línea 306:
  
 ===== Reescribiendo funciones usando map, fold y filter ===== ===== Reescribiendo funciones usando map, fold y filter =====
 +
 +
 +
  
 ==== Ejercicios ==== ==== Ejercicios ====
  
   * Escribir //duplicar// y //multiplicar// con //mapa//.   * Escribir //duplicar// y //multiplicar// con //mapa//.
 +    * Reescribir ambas utilizando aplicación parcial sobre //mapa// para evitar escribir el argumento de la lista.
 +  * Utilizando //mapa// escribir la función //largos :: [String] -> [Int]// que dada una lista de cadenas, retorna la lista con la longitud de cada una.
   * Escribir //soloPares// y //quitar0s// con //filtro//.   * Escribir //soloPares// y //quitar0s// con //filtro//.
 +    * Reescribir ambas utilizando aplicación parcial sobre //mapa// para evitar escribir el argumento de la lista.
 +  * Escribir //concatenaInt// usando //acumula//.
 +  * Escribir //sumatoria// usando aplicación parcial con //acumula//.
   * Escribir //paraTodoInt// usando //acumula//.   * Escribir //paraTodoInt// usando //acumula//.
   * Escribir //longitud// usando //acumula//.   * Escribir //longitud// usando //acumula//.
   * Escribir //reversa// usando //acumula//.   * Escribir //reversa// usando //acumula//.
-  * **DIFÍCIL** Escribir //mapa// y //filtro// usando //acumula//.+  * **(DIFÍCIL)** Escribir //mapa// y //filtro// usando //acumula//.
introalg/taller07_4.1179165006.txt.gz · Última modificación: 2018/08/10 03:03 (editor externo)