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 17:48] – nicolasw | introalg: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 | + | 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 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//, | + | Las funciones de //tipo aplicación//, |
< | < | ||
Línea 96: | 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 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 | + | Vemos nuevamente |
- | Se dice que en Haskell las funciones son // | + | De nuevo, 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 131: | Línea 139: | ||
=== Ejercicio === | === Ejercicio === | ||
- | * Definir la función //mapNumero.f.xs//, //mapNumero | + | * Definir la función //mapNumeros.f.xs//, //mapNumeros |
probar con mapNumeros.(*2).[0, | probar con mapNumeros.(*2).[0, | ||
+ | |||
+ | |||
Línea 141: | 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 167: | Línea 177: | ||
probar con filtraNumeros.entre0y9.[], | probar con filtraNumeros.entre0y9.[], | ||
+ | |||
+ | |||
Línea 186: | 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 194: | Línea 206: | ||
concatenaInt :: [[Int]] -> [Int] | concatenaInt :: [[Int]] -> [Int] | ||
concatenaInt [] = [] | concatenaInt [] = [] | ||
- | concatenaInt (xs:xss) = xs ++ concatenaInt xss | + | concatenaInt (xs:xss) = (++) xs (concatenaInt xss) |
</ | </ | ||
Línea 228: | 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 250: | Línea 262: | ||
filtro p (x:xs) = | filtro p (x:xs) = | ||
</ | </ | ||
+ | |||
+ | |||
==== Acumuladores (fold) ==== | ==== Acumuladores (fold) ==== | ||
Línea 263: | 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 292: | 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.1179164883.txt.gz · Última modificación: 2018/08/10 03:03 (editor externo)