introalg:taller09_6
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:taller09_6 [2009/05/04 13:05] – laura | introalg:taller09_6 [2018/08/10 03:03] (actual) – editor externo 127.0.0.1 | ||
---|---|---|---|
Línea 48: | Línea 48: | ||
Las listas son una estructura que por definición contiene un número arbitrario de elementos, por lo tanto son el contexto natural para aplicar funciones recursivas. Hemos distinguido tres grandes tipos de funciones recursivas en listas: | Las listas son una estructura que por definición contiene un número arbitrario de elementos, por lo tanto son el contexto natural para aplicar funciones recursivas. Hemos distinguido tres grandes tipos de funciones recursivas en listas: | ||
* **aplicaciones**: | * **aplicaciones**: | ||
+ | |||
aplica :: [a] -> [b] | aplica :: [a] -> [b] | ||
+ | |||
donde el tipo de la lista inicial no necesariamente tiene que ser el mismo que el de la lista resultante, ya que la función que aplicamos a cada elemento puede cambiar ese tipo (por ejemplo, si cambiamos de booleano a 0 o 1). | donde el tipo de la lista inicial no necesariamente tiene que ser el mismo que el de la lista resultante, ya que la función que aplicamos a cada elemento puede cambiar ese tipo (por ejemplo, si cambiamos de booleano a 0 o 1). | ||
* **filtros**: | * **filtros**: | ||
+ | |||
filtra :: [a] -> [a] | filtra :: [a] -> [a] | ||
+ | |||
donde el tipo de la lista inicial tiene que ser exactamente el mismo que el de la lista resultante, ya que devolvemos elementos del mismo tipo solamente que podemos devolver menos elementos, descartando los que no cumplen el predicado (por ejemplo, los que no son pares). | donde el tipo de la lista inicial tiene que ser exactamente el mismo que el de la lista resultante, ya que devolvemos elementos del mismo tipo solamente que podemos devolver menos elementos, descartando los que no cumplen el predicado (por ejemplo, los que no son pares). | ||
* **acumuladores**: | * **acumuladores**: | ||
+ | |||
acumula :: [a] -> b | acumula :: [a] -> b | ||
+ | |||
fíjense que el tipo del resultado es distinto que el de la lista inicial, de hecho, ni siquiera es necesario que sea una lista. El tipo del resultado es exactamente **el neutro de la operación** que estemos aplicando para acumular el resultado (por ejemplo, en una sumatoria es el 0, en una productoria el 1, etc.). | fíjense que el tipo del resultado es distinto que el de la lista inicial, de hecho, ni siquiera es necesario que sea una lista. El tipo del resultado es exactamente **el neutro de la operación** que estemos aplicando para acumular el resultado (por ejemplo, en una sumatoria es el 0, en una productoria el 1, etc.). | ||
Línea 77: | Línea 83: | ||
< | < | ||
- | cuadrado :: Int -> Int | ||
- | cuadrado x = x^2 | ||
- | |||
cuadrados :: [Int] -> [Int] | cuadrados :: [Int] -> [Int] | ||
cuadrados [] = [] | cuadrados [] = [] | ||
cuadrados (x:xs) = cuadrado x : cuadrados xs | cuadrados (x:xs) = cuadrado x : cuadrados xs | ||
- | </ | ||
- | < | + | cuadrado |
- | rangoEdades | + | cuadrado |
- | rangoEdades [] = [] | + | |
- | rangoEdades (x:xs) = rangoEdad | + | |
</ | </ | ||
Línea 98: | Línea 98: | ||
- | Ahora que sabemos esto, resolvamos la función '' | + | Ahora que sabemos esto, resolvamos la función '' |
Línea 108: | Línea 108: | ||
< | < | ||
- | esPar :: Int -> Bool | + | soloTrue |
- | esPar = esDivisor 2 | + | soloTrue [] = [] |
+ | soloTrue (x:xs) | x == True = x : soloTrue xs | ||
+ | | otherwise = | ||
+ | </ | ||
+ | < | ||
soloPares :: [Int] -> [Int] | soloPares :: [Int] -> [Int] | ||
soloPares [] = [] | soloPares [] = [] | ||
soloPares (x:xs) | esPar x | soloPares (x:xs) | esPar x | ||
| otherwise = soloPares xs | | otherwise = soloPares xs | ||
+ | |||
+ | esPar :: Int -> Bool | ||
+ | esPar x = mod x 2 == 0 | ||
</ | </ | ||
< | < | ||
- | primeraEsM :: [Char] -> Bool | ||
- | primeraEsM xs = cabeza xs == ' | ||
- | |||
empiezaM :: [String] -> [String] | empiezaM :: [String] -> [String] | ||
empiezaM [] = [] | empiezaM [] = [] | ||
empiezaM (x:xs) | primeraEsM x = x : empiezaM xs | empiezaM (x:xs) | primeraEsM x = x : empiezaM xs | ||
| otherwise | | otherwise | ||
+ | |||
+ | primeraEsM :: [Char] -> Bool | ||
+ | primeraEsM xs = head xs == ' | ||
</ | </ | ||
Línea 134: | Línea 141: | ||
| otherwise = _____________ xs | | otherwise = _____________ xs | ||
- | Ahora que sabemos esto, resolvamos la función '' | + | Ahora que sabemos esto, resolvamos la función '' |
==== Acumuladores (foldr) ==== | ==== Acumuladores (foldr) ==== | ||
Línea 149: | Línea 156: | ||
< | < | ||
- | producto :: Int -> Int -> Int | ||
- | producto x y = x*y | ||
- | |||
productoria :: [Int] -> Int | productoria :: [Int] -> Int | ||
productoria [] = 1 | productoria [] = 1 | ||
productoria (x:xs) = producto x (productoria xs) | productoria (x:xs) = producto x (productoria xs) | ||
+ | |||
+ | producto :: Int -> Int -> Int | ||
+ | producto x y = x*y | ||
</ | </ | ||
Línea 176: | Línea 183: | ||
- | Como el resultado de la función no es una lista, el resultado del caso base no es una lista vacía. El resultado del caso base debe ser definido para cada función, ya que debe ser el neutro del operador que se utilice en la función. Por lo tanto, en los acumuladores tendremos un argumento más que en las aplicaciones y los filtros, justamente, el neutro. | + | Como el resultado de la función no es una lista, el resultado del caso base no es una lista vacía. El resultado del caso base debe ser definido para cada función, ya que debe ser el **neutro del operador** que se utilice en la función. |
- | Ahora que sabemos esto, resolvamos la función '' | + | Ahora que sabemos esto, resolvamos la función '' |
- | Otro ejemplo: la función '' | + | Otro ejemplo: la función '' |
Más ejercicios: la función '' | Más ejercicios: la función '' | ||
Línea 191: | Línea 198: | ||
Muchas funciones necesitan hacer cosas complejas, y para eso combinan dos o más de los tipos de funciones recursivas en listas que hemos visto. Veamos los siguientes ejemplos: | Muchas funciones necesitan hacer cosas complejas, y para eso combinan dos o más de los tipos de funciones recursivas en listas que hemos visto. Veamos los siguientes ejemplos: | ||
- | * La función '' | + | La función '' |
- | * La función '' | + | < |
- | * La función '' | + | sumaPares :: [Int] -> Int |
+ | sumaPares [] = 0 | ||
+ | sumaPares (x:xs) | mod x 2 == 0 = x + sumaPares xs | ||
+ | | otherwise | ||
+ | </ | ||
+ | Fíjense que el resultado es el resultado propio de un acumulador, es decir, no es una lista, por lo tanto para el caso base tenemos que usar el neutro de la operación, en este caso, como la operación es la suma, el resultado para el caso base es el 0. | ||
+ | |||
+ | También podríamos definir la función de forma que queden más separados el filtro y el acumulador, definiendo las funciones por separado y usándolas luego combinadas, primero aplicando el filtro y luego sumando los elementos que quedaron seleccionados en el filtro. Para indicar que primero se tiene que aplicar una operación y después la otra, usamos paréntesis: | ||
+ | < | ||
+ | sumaPares' | ||
+ | sumaPares' | ||
+ | |||
+ | pares :: [Int] -> [Int] | ||
+ | pares [] = [] | ||
+ | pares (x:xs) | mod x 2 == 0 = x : pares xs | ||
+ | | otherwise | ||
+ | |||
+ | suma :: [Int] -> Int | ||
+ | suma [] = 0 | ||
+ | suma (x:xs) = x + suma xs | ||
+ | </ | ||
+ | Fíjense que ahora no tenemos que definir caso base y caso recursivo para definir '' | ||
+ | |||
+ | Pero no les resultan muy familiares estas funciones '' | ||
+ | < | ||
+ | sumaPares'' | ||
+ | sumaPares'' | ||
+ | </ | ||
+ | Corto, fácil de leer y reusando código! Qué más queremos! ;-) | ||
+ | |||
+ | Veamos otros ejemplos: la función '' | ||
+ | |||
+ | Cómo calculamos la función '' | ||
===== Recursión en dos argumentos ===== | ===== Recursión en dos argumentos ===== | ||
Línea 232: | Línea 271: | ||
====== Ejercicios ====== | ====== Ejercicios ====== | ||
+ | |||
+ | ==== Repaso de prolog ==== | ||
+ | |||
+ | * A partir de la siguiente base de conocimiento en prolog, crear las reglas necesarias para que el intérprete nos diga si una persona alérgica a la frutilla puede comer helado de frutilla: | ||
+ | < | ||
+ | esAlérgico(pepe, | ||
+ | esAlérgico(juan, | ||
+ | esAlérgico(maría, | ||
+ | |||
+ | tiene(helado, | ||
+ | tiene(torta, | ||
+ | </ | ||
+ | |||
+ | ==== Repaso de haskell ==== | ||
* Definir la función **estanOrdenados**, | * Definir la función **estanOrdenados**, | ||
Línea 242: | Línea 295: | ||
* Definir la función **restaPositiva**, | * Definir la función **restaPositiva**, | ||
+ | |||
+ | * Definir la función **esSigno**, | ||
+ | Ejemplo: esSigno ``aries'' | ||
+ | Ejemplo: esSigno ``leo'' | ||
+ | |||
+ | * Definir la función **cuatroCabezas**, | ||
+ | Ayuda: se puede usar la función " | ||
+ | |||
+ | ==== Funciones recursivas ==== | ||
* Definir la función **librosRecomendados**, | * Definir la función **librosRecomendados**, | ||
Línea 247: | Línea 309: | ||
* Definir la función **peliculasAccion**, | * Definir la función **peliculasAccion**, | ||
- | Ejemplo: peliculasAccion [(``Rambo'' | + | Ejemplo: peliculasAccion [("Rambo",True),("E.T.",False),("Duro de Matar",True)] = ["Rambo","Duro de Matar"]. |
- | + | ||
- | * Definir la función **esSigno**, | + | |
- | Ejemplo: esSigno ``aries'' | + | |
- | Ejemplo: esSigno ``leo'' | + | |
* Definir la función **cuadrados**, | * Definir la función **cuadrados**, | ||
Línea 270: | Línea 328: | ||
* Definir la función **cuantos0**, | * Definir la función **cuantos0**, | ||
Ayuda: recordar cómo se hizo la función " | Ayuda: recordar cómo se hizo la función " | ||
- | |||
- | * Definir la función **cuatroCabezas**, | ||
- | Ayuda: se puede usar la función " | ||
* Definir la función **cuantosEntre**, | * Definir la función **cuantosEntre**, | ||
Línea 284: | Línea 339: | ||
* Definir la función // | * Definir la función // | ||
- | |||
- | * Definir la función // | ||
Línea 291: | Línea 344: | ||
* Definir //iguales :: Eq a => [a] -> [a] -> Bool// que decide si dos listas son iguales. | * Definir //iguales :: Eq a => [a] -> [a] -> Bool// que decide si dos listas son iguales. | ||
+ | |||
* Definir // | * Definir // | ||
+ | |||
* Activar con '': | * Activar con '': | ||
+ | |||
* Supongamos ahora que el listado de las personas que reciben subsidio por desempleo es una lista de tuplas // | * Supongamos ahora que el listado de las personas que reciben subsidio por desempleo es una lista de tuplas // | ||
< | < |
introalg/taller09_6.1241442322.txt.gz · Última modificación: 2018/08/10 03:03 (editor externo)