Subido por jorgedefran1

PP 10 Tema 4 Funciones Recursivas

Anuncio
Funciones recursivas
y de orden superior
Paradigmas de programación
Grado en Ingeniería del Software
Soto Montalvo
soto.montalvo@urjc.es
(Adaptado por Eduardo G. Pardo)
Paradigmas de Programación
Grado en Ingeniería del Software
Objetivos
• Aprender a definir funciones de forma más compacta
mediante la recursividad y el orden superior
• Aprender a definir funciones anónimas y el concepto de
polimorfismo
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
2
Contenidos
1. Funciones recursivas
2. Funciones de orden superior
3. Expresiones lambda
4. Polimorfismo
5. Bibliografía
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
3
Contenidos
1. Funciones recursivas
2. Funciones de orden superior
3. Expresiones lambda
4. Polimorfismo
5. Bibliografía
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
4
Funciones recursivas
• Una definición se dice que es recursiva si el concepto
que se está definiendo participa (aparece) en la
definición
• Ejemplo: La definición de un factorial de un entero
positivo se puede realizar de forma recursiva
n! = n*(n-1)*(n-2)*...*2*1
(n-1)! = (n-1)*(n-2)*...*2*1
Entonces:
n! = n*(n-1)!
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
5
Funciones recursivas
• Ejemplo: cálculo de 3!
3! = 3*2! = 3*2*1! = 3*2*1*0!
Por definición: 0! = 1 (Caso base)
• De forma general se puede establecer que para el
factorial:
 1, si
n! = 
n * ( n − 1)!,
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
n=0
si
n 1
6
Funciones recursivas
• En una definición recursiva deben existir
obligatoriamente:
• Caso(s) base(s): no provocan un nuevo cálculo
recursivo, finalizando la recursión, con lo que se
puede obtener una solución
• Caso(s) recursivo(s): aquéllos que provocan la
realización de nuevos cálculos recursivos (sobre
datos más “pequeños”)
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
7
Funciones recursivas
• En Haskell la función factorial sería:
factorial:: Int -> Int
factorial n = if n == 0 then 1
else n * factorial (n-1)
• Si se combina el uso de patrones con la recursividad
la definición de la función queda más compacta
factorial:: Int -> Int
factorial 0 = 1
factorial n = n * factorial (n-1)
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
8
Funciones recursivas
• Tipos de recursividad:
• Recursividad lineal: la aplicación de la función
contiene una única llamada recursiva
• Recursividad no lineal: la aplicación de la función
contiene más de una llamada recursiva (conocida
también como recursividad múltiple)
• Ejemplo: serie de Fibonacci, ya que
recursivamente la función se aplica más de una vez
1, si n = 0  n = 1

Fibonacci (n) = 
 Fibonacci( n − 1) + Fibonacci( n − 2),
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
si n  2
9
Funciones recursivas
• Árbol de llamadas recursivas (Fibonacci(5))
Fib(5)
Fib(3)
Fib(4)
Fib(3)
Fib(2)
Fib(2)
Fib(2)
Fib(1)
Fib(1)
Fib(0)
1
1
Fib(1)
1
Fib(0)
1
1
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
Fib(1)
1
Fib(1)
Fib(0)
1
1
10
Funciones recursivas
• La recursividad lineal se puede clasificar, a su vez, en:
• Recursividad final o de cola: si la llamada recursiva es
la operación más externa, es decir, es la última
operación que se ejecuta
• Recursividad no final: cuando la recursividad es lineal,
pero no de cola
• Ejemplo: ¿Qué tipo de recursividad tiene el factorial?
n! = n*(n-1)!
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
(No final)
11
Funciones recursivas
• La recursividad final es especialmente interesante ya que
conduce a un método sencillo y alternativo de construir
programas (técnica de los parámetros de acumulación)
• El método consiste en definir una función auxiliar con
algún(os) parámetro(s) adicional(es) para calcular el
resultado
• Los parámetros suelen ser internos para no tener que
recordarlos a la hora de usar las funciones
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
12
Funciones recursivas
r , si n = 1

fact 2( n, r ) = 
 fact 2( n − 1, n * r ), si n  1
• Ejemplo: factorial
fact:: Int -> Int
fact n = fact2(n,1)
fact2:: (Int,Int) -> Int
fact2 (n,r) = if n == 1 then r
else fact2(n-1,r*n)
Evaluación: fact 4 → fact2(4,1) → fact2(3,4) → fact2(2,12)
→ fact2(1,24) → 24
(Recursividad final, ya que la llamada recursiva es la última
operación que se efectúa)
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
13
Funciones recursivas
• En el ejemplo del factorial, en su versión de parámetros
de acumulación, el resultado calculado por fact2 es el
mismo que el de fact
• A su vez, el segundo parámetro de fact2 “acumula” el
valor del resultado que se devuelve cuando n=1
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
14
Funciones recursivas
• La técnica de parámetros de acumulación tiene cierta
similitud con los bucles en la programación imperativa
• Ejemplo: bucle para el cálculo del factorial en Pascal
...
r := 1;
while n > 1 do
Begin
r := r*n;
n := n-1;
end;
…
Paradigmas de Programación
Grado en Ingeniería del Software
15
Contenidos
1. Funciones recursivas
2. Funciones de orden superior
3. Expresiones lambda
4. Polimorfismo
5. Bibliografía
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
16
Funciones de orden superior
• Consiste en tratar a las funciones como datos del lenguaje:
• Se pueden tener funciones como argumentos de otras
funciones
• Se pueden tener funciones como resultado de otras
funciones (composición de funciones)
• Se pueden tener estructuras de datos que contienen
funciones
• Ventajas:
• Programas más concisos
• Programas genéricos
• Potenciación de la reutilización
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
17
Funciones de orden superior
• Funciones como argumento
incremento :: Int -> Int
incremento x = x + 1
dosVeces :: (Int -> Int) -> Int -> Int
dosVeces f x = f (f x)
ModuleName> dosVeces (*3) 2
3
ModuleName> dosVeces doble
18
12
ModuleName> dosVeces incremento 2
4
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
18
Funciones de orden superior
• Funciones como resultado
• Se utiliza mucho con la currificación
sumac:: Int -> (Int -> Int)
sumac x y = x + y
ModuleName> sumac 2 3
5
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
19
Funciones de orden superior
• Algunas funciones de orden superior sobre listas:
función map
• map f xs, obtiene una lista resultado de aplicar la
función f a cada elemento de la lista xs
ModuleName> map (*2) [3,4,7]
[6,8,14]
Pruebas1> map even [1..5]
[False,True,False,True,False]
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
20
Funciones de orden superior
• Algunas funciones de orden superior sobre listas:
función filter
• filter p xs, devuelve los elementos de la lista que
cumplen alguna condición
ModuleName>filter even [1..10]
[2, 4, 6, 8, 10]
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
21
Funciones de orden superior
• Algunas funciones de orden superior sobre listas:
función all
• all p xs, verifica si todos los elementos de la lista xs
cumplen la propiedad p.
ModuleName> all even [2,4,8]
True
ModuleName> all even [1,4,8]
False
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
22
Funciones de orden superior
• Algunas funciones de orden superior sobre listas:
función any
• any p xs, verifica si algún elemento de la lista xs
cumple la propiedad p.
ModuleName> any even [1,2,3]
True
ModuleName> any even [1,3,5]
False
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
23
Funciones de orden superior
• Función de plegado de listas por la derecha:
función foldr
• Muchas de las funciones que se definen sobre listas
siguen el siguiente patrón recursivo:
• Si el argumento es la lista vacía, se devuelve cierto
valor base (correspondiente al caso base de la
definición).
• En otro caso, se opera, mediante cierta función u
operador (plegador), la cabeza de la lista y una
llamada recursiva con la cola de la lista.
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
24
Funciones de orden superior
• Función de plegado de listas por la derecha:
función foldr
• Ejemplos de funciones sobre listas con patrón similar
sumaLista :: [Int] -> Int
sumaLista [] = 0
sumaLista (x:xs) = x + sumaLista xs
(El valor base es 0 y el plegador es (+))
productoLista :: [Int] -> Int
productoLista [] = 1
productoLista (x:xs) = x * productoLista xs
(El valor base es 1 y el plegador es (*))
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
25
Funciones de orden superior
• Función de plegado de listas por la derecha:
función foldr
• Ejemplos de funciones sobre listas con patrón similar
verdad:: [Bool] -> Bool
verdad [] = True
verdad (x:xs) = x && verdad xs
(El valor base es True y el plegador es (&&))
concatenar:: [[Int]] -> [Int]
concatenar [] = []
concatenar (sublista:resto) = sublista ++ concatenar resto
(El valor base es [] y el plegador es (++))
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
26
Funciones de orden superior
• Función de plegado de listas por la derecha:
función foldr
• Esquema básico de la recursión sobre listas es algo como:
f [] = valor
f (x:xs) = x ’operación’ (f xs)
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
27
Funciones de orden superior
• La función foldr hace una abstracción del valor base y el
plegador, de forma que:
• Recibe como parámetros un operador, un valor inicial y
una lista.
• Pliega la lista a un único valor colocando el operador
entre los elementos de la lista.
• Empieza por la derecha con el valor inicial.
foldr (+) e [w,x,y,z]
es igual al valor de la expresión:
(w + (x + (y + (z + e))))
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
28
Funciones de orden superior
• Función de plegado de listas por la derecha:
función foldr
• Redefinición de funciones utilizando foldr:
sumaLista :: [Int] -> Int
sumaLista = foldr (+) 0
> sumaLista [1,2,3]
6
productoLista :: [Int] -> Int
productoLista = foldr (*) 1
> productoLista [2,3,2]
12
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
29
Funciones de orden superior
• Función de plegado de listas por la derecha:
función foldr
• Redefinición de funciones utilizando foldr:
verdad :: [Bool] -> Bool
verdad = foldr (&&) True
> verdad [1<2, False, 3*4<20]
False
concatenar:: [[Int]] -> [Int]
concatenar = foldr (++) []
> concatenar [[1,2],[10],[4,7]]
[1,2,10,4,7]
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
30
Funciones de orden superior
• Función de plegado de listas por la izquierda:
función foldl
• Realiza el plegado de la lista de izquierda a derecha
• Recibe como parámetros un operador, un valor inicial y
una lista.
• Pliega la lista a un único valor colocando el operador entre los
elementos de la lista
• Empieza por la izquierda con el valor inicial
foldl op e [x1,x2,x3] ; (((e op x1) op x2) op x3
ModuleName> foldl (-) 3 [2,3,5]
-7
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
31
Contenidos
1. Funciones recursivas
2. Funciones de orden superior
3. Expresiones lambda
4. Polimorfismo
5. Bibliografía
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
32
Expresiones lambda
• Se pueden definir funciones anónimas mediante
expresiones lambda (también denominadas –
expresiones)
x -> x * 2
• En Haskell se escribe \ en lugar de la letra griega lambda
\x -> x * 2
ModuleName> (\x -> x * 2) 5
10
• La notación proviene del calculo lambda, en el cual está
basado Haskell
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
33
Expresiones lambda
• Son muy útiles como argumentos de funciones de Orden
Superior
dosVeces :: (Int -> Int) -> Int -> Int
dosVeces f x = f (f x)
ModuleName> dosVeces (\x->x + 1) 20
22
invertirLista :: [Int] -> [Int]
invertirLista = foldr (\x lista -> lista ++ [x]) []
ModuleName> invertirLista [1,2,3]
[3,2,1]
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
34
Expresiones lambda
• Evitan tener que dar nombre a funciones que sólo se van a
utilizar una vez
impares n = map f [0..n-1]
where f x = x
* 2 + 1
ModuleName> impares 5
[1,3,5,7,9]
odds n = map (\x->x * 2 + 1) [0..n-1]
ModuleName> odds 5
[1,3,5,7,9]
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
35
Contenidos
1. Funciones recursivas
2. Funciones de orden superior
3. Expresiones lambda
4. Polimorfismo
5. Bibliografía
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
36
Polimorfismo
• Haskell da la opción de incluir la declaración de cada una
de las funciones que definimos en un módulo
• Si incluimos la declaración, estamos particularizando el
uso de la función a un tipo concreto de dato
• Si no incluimos la declaración, la función podrá ser
aplicada a todo tipo de dato compatible con las
operaciones incluidas en la definición de la función:
POLIMORFISMO.
• Aumenta la reusabilidad
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
37
Polimorfismo
• Se dice que un tipo es polimórfico si en la expresión que
lo declara aparece al menos una variable
• En Haskell es posible declarar una función usando un tipo
genérico que desempeña el papel de cualquier tipo
compatible con la definición
• Se dice que un tipo es polimórfico si en la expresión que
lo declara aparece al menos una variable
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
38
Polimorfismo
• Ejemplo:
longEntero:: [Int]->Int
longEntero []=0
longEntero (_:xs)= 1 + longEntero xs
Variable de Tipo
(vale cualquier
nombre)
Paradigmas de Programación
Grado en Ingeniería del Software
longChar:: [Char]->Int
longChar []=0
longChar (_:xs)= 1 + longChar xs
longitud:: [a]->Int
longitud []=0
longitud (_:xs)= 1 + longitud xs
GIS
39
Contenidos
1. Funciones recursivas
2. Funciones de orden superior
3. Expresiones lambda
4. Polimorfismo
5. Bibliografía
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
40
Bibliografía
• Haskell: The Craft of Functional Programming (2nd
Edition). Simon Thompson. Addison-Wesley.
• RAZONANDO CON HASKELL. Un curso sobre
programación funcional. Blas Carlos Ruiz, Francisco
Gutiérrez, Pablo Guerrero, José E. Gallardo. Ediciones
Paraninfo S.A.
• Programación Funcional. Jeroen Fokker. Universidad
de Utrecht, Departamento de Informática, 1996.
• Introducción a la Programación Funcional con
Haskell (Segunda edición). R. Bird. Prentice Hall.
Paradigmas de Programación
Grado en Ingeniería del Software
GIS
41
Descargar