introalg:taller07_4
Diferencias
Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previa | ||
| introalg:taller07_4 [2007/05/14 14:44] – nicolasw | introalg:taller07_4 [2025/11/15 13:47] (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 | + | Tomemos la siguente función Haskell que es una ligera variación de // |
| < | < | ||
| Línea 17: | Línea 19: | ||
| Esto lo podemos leer como que // | Esto lo podemos leer como que // | ||
| - | 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 | ||
| Main> :t esDivisor 2 | Main> :t esDivisor 2 | ||
| Línea 28: | Línea 31: | ||
| < | < | ||
| esPar :: Int -> Bool | esPar :: Int -> Bool | ||
| - | esPar = esDivisor 2 | + | esPar x = esDivisor 2 x |
| </ | </ | ||
| 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** |
| < | < | ||
| esPar' :: Int -> Bool | esPar' :: Int -> Bool | ||
| - | esPar' | + | esPar' = esDivisor 2 |
| </ | </ | ||
| - | Esta forma de denotar | + | Esta forma de escribir |
| 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, | [True, | ||
| - | 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 |
| < | < | ||
| Línea 71: | Línea 74: | ||
| [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 86: | 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//, | + | Las funciones de //tipo aplicación//, |
| < | < | ||
| Línea 95: | Línea 104: | ||
| < | < | ||
| - | veintePorCiento : [Float] -> [Float] | + | veintePorCiento |
| veintePorCiento [] = [] | veintePorCiento [] = [] | ||
| veintePorCiento (x:xs) = 0.2*x : veintePorCiento xs | veintePorCiento (x:xs) = 0.2*x : veintePorCiento xs | ||
| Línea 117: | 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. | ||
| + | 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**. | ||
| - | * Definir la función // | + | De nuevo, se dice que en Haskell las funciones son // |
| - | + | ||
| - | probar con mapNumeros.(*2).[0, | + | |
| - | + | ||
| - | + | ||
| - | Esta función es la primera que creamos que utiliza **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 // | + | |
| Esto no ocurre en la mayoría de los //lenguajes imperativos// | Esto no ocurre en la mayoría de los //lenguajes imperativos// | ||
| Línea 132: | Línea 135: | ||
| esDivisor :: Int -> (Int -> Bool) | esDivisor :: Int -> (Int -> Bool) | ||
| esDivisor 2 :: Int -> Bool | esDivisor 2 :: Int -> Bool | ||
| + | |||
| + | |||
| + | === Ejercicio === | ||
| + | |||
| + | * Definir la función // | ||
| + | |||
| + | probar con mapNumeros.(*2).[0, | ||
| + | |||
| + | |||
| + | |||
| ==== Filtros ==== | ==== Filtros ==== | ||
| Línea 138: | Línea 151: | ||
| < | < | ||
| - | esPar :: Int -> Bol | + | esPar :: Int -> Bool |
| - | esPar x = x `mod` 2 == 0 | + | esPar = esDivisor |
| soloPares :: [Int] -> [Int] | soloPares :: [Int] -> [Int] | ||
| Línea 158: | Línea 171: | ||
| Entonces plantemos el mismo tipo de ejercicio, una generalización que tome como primer parámetro un **predicado**, | Entonces plantemos el mismo tipo de ejercicio, una generalización que tome como primer parámetro un **predicado**, | ||
| + | |||
| + | === Ejercicio === | ||
| * Definir la función // | * Definir la función // | ||
| probar con filtraNumeros.entre0y9.[], | probar con filtraNumeros.entre0y9.[], | ||
| + | |||
| + | |||
| + | |||
| Línea 180: | Línea 198: | ||
| productoria :: [Int] -> Int | productoria :: [Int] -> Int | ||
| - | productoria [] | + | productoria [] |
| productoria (x:xs) = producto x (productoria xs) | productoria (x:xs) = producto x (productoria xs) | ||
| </ | </ | ||
| Línea 188: | Línea 206: | ||
| concatenaInt :: [[Int]] -> [Int] | concatenaInt :: [[Int]] -> [Int] | ||
| concatenaInt [] = [] | concatenaInt [] = [] | ||
| - | concatenaInt (xs:xss) = xs ++ concatenaInt xss | + | concatenaInt (xs:xss) = (++) xs (concatenaInt xss) |
| </ | </ | ||
| - | Hacer esta primera generalización. | + | === Ejercicio === |
| + | |||
| + | Definir la primera generalización. | ||
| * Definir la función // | * Definir la función // | ||
| Línea 202: | Línea 222: | ||
| probar con acumulaInt.(+).0.[1, | probar con acumulaInt.(+).0.[1, | ||
| - | |||
| ===== Escribamos las versiones más generales ===== | ===== Escribamos las versiones más generales ===== | ||
| Línea 221: | Línea 240: | ||
| < | < | ||
| - | mapa : (a -> b) -> [a] -> [b] | + | mapa :: (a -> b) -> [a] -> [b] |
| mapa f [] = | mapa f [] = | ||
| mapa f (x:xs) = | mapa f (x:xs) = | ||
| Línea 243: | Línea 262: | ||
| filtro p (x:xs) = | filtro p (x:xs) = | ||
| </ | </ | ||
| + | |||
| + | |||
| ==== Acumuladores (fold) ==== | ==== Acumuladores (fold) ==== | ||
| Línea 256: | Línea 277: | ||
| Detectamos: | Detectamos: | ||
| - | * Un " | + | * Un "**cero**" respecto a la acumulación (//True// es neutro de la conjunción). |
| * Una función de acumulación que a partir del elemento actual y lo acumulado en la llamada recursiva sobre //xs//, obtiene el valor de lo acumulado en el total //x:xs//. | * Una función de acumulación que a partir del elemento actual y lo acumulado en la llamada recursiva sobre //xs//, obtiene el valor de lo acumulado en el total //x:xs//. | ||
| - | Podemos reescribirla de la siguiente manera | + | Podemos reescribirla de la siguiente manera |
| < | < | ||
| - | ceroUnoyAnteriores | + | ceroUnoYAnteriores |
| - | ceroUnoyAnteriores | + | ceroUnoYAnteriores |
| todos0y1' | todos0y1' | ||
| todos0y1' | todos0y1' | ||
| - | todos0y1' | + | todos0y1' |
| </ | </ | ||
| Línea 285: | Línea 306: | ||
| ===== Reescribiendo funciones usando map, fold y filter ===== | ===== Reescribiendo funciones usando map, fold y filter ===== | ||
| + | |||
| + | |||
| + | |||
| ==== Ejercicios ==== | ==== Ejercicios ==== | ||
| * Escribir // | * Escribir // | ||
| + | * 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 // | * Escribir // | ||
| + | * Reescribir ambas utilizando aplicación parcial sobre //mapa// para evitar escribir el argumento de la lista. | ||
| + | * Escribir // | ||
| + | * Escribir // | ||
| * Escribir // | * Escribir // | ||
| * Escribir // | * Escribir // | ||
| * Escribir //reversa// usando // | * Escribir //reversa// usando // | ||
| - | * **DIFÍCIL** Escribir //mapa// y //filtro// usando // | + | * **(DIFÍCIL)** Escribir //mapa// y //filtro// usando // |
introalg/taller07_4.1179164690.txt.gz · Última modificación: (editor externo)
