Tema 6: Funciones recursivas

Documentos relacionados
Tema 4: Definición de funciones

Tema 4: Definición de funciones

Tema 5: Definiciones de listas por comprensión

Tema 5: Definiciones de listas por comprensión

Tema 3: Tipos y clases

Tema 3: Tipos y clases

Tema 3: Tipos y clases

Tema 3: Tipos y clases

Tema 2: Introducción a la programación con Haskell

Tema 9: Declaraciones de tipos y clases

Tema 12: Programas interactivos

Tema 2: Introducción a la programación con Haskell

Tema 9: Declaraciones de tipos y clases

Tema 13: Aplicaciones de programación funcional

Tema 13: Programas interactivos

Tema 11: Analizadores sintácticos funcionales

Tema 12: Analizadores sintácticos funcionales

Programación Declarativa Haskell Informática Sistemas Curso Pepe Gallardo Universidad de Málaga. Tema 8. Listas

Programación Funcional

n! = 1 2 n 0! = 1 (n+1)! = (n + 1) n!

Ejercicios de programación funcional con Haskell

Informática Haskell Matemáticas Curso Pepe Gallardo Universidad de Málaga. Tema 8. Listas

Tema 21: Algoritmos de exploración de grafos

Listas y Recursión. Taller de Álgebra I. Primer Cuatrimestre de 2015

Tema 12: Programas interactivos

Tema 12: Programas interactivos

Temas de Programación declarativa ( ) José A. Alonso Jiménez

Manos a la obra: Recursión, división y listas

Exámenes de Programación funcional con Haskell ( )

data Tree a = Tip Node a (Tree a) (Tree a) deriving Show

Guía 2: Listas, recursión e inducción

Programación Funcional Haskell Clase 21

Programación Funcional en Haskell

El sistema de clases de Haskell. Introducción

Programación Funcional Haskell Clase 22

Guía 2: Funciones, listas, recursión e inducción

Tema 7. El sistema de clases

Tipos algebraicos y abstractos. Algoritmos y Estructuras de Datos I. Tipos algebraicos

Tema 11. Listas infinitas

Tipos de datos algebraicos

Programación declarativa ( )

Tema Árboles generales. 9.2 Árboles binarios 9.3 Árboles de búsqueda

Tipos paramétricos y recursivos

Programación Declarativa Curso

Para entender la recursividad primero tenemos que entender la recursividad

Introducción a la Programación Genérica

Tema 2. Tipos predefinidos

Tema Árboles binarios fmap para árboles binarios Plegado de árboles binarios

Tipos de datos y clases de tipos

Números primos y criterios de divisibilidad

Guardas y Tipos de datos

Programación Declarativa UNIVERSIDAD DE MÁLAGA

RAZONANDO CON HASKELL UN CURSO SOBRE PROGRAMACIÓN FUNCIONAL. A Charo, Pepa, Ana y Chari INTERNATIONAL THOMSON EDITORES SPAIN PARANINFO

Árboles generales. Un árbol es una estructura no lineal acíclica utilizada para organizar información de forma eficiente. La definición es recursiva:

Tema 3. Patrones y Definiciones de Funciones

Tema 2: Listas, aritmética y operadores

Introducción a Haskell. Cecilia Manzino

Tema 3. Patrones y Definiciones de Funciones

Introducción. Haskell

Programación Funcional Haskell Clase 19

Isabelle como un lenguaje funcional

Programación funcional

EJERCICIOS DE LENGUAJES Y PARADIGMAS DE PROGRAMACIÓN (CUESTIONES DE EXAMEN) PROGRAMACIÓN FUNCIONAL

Programación I Recursividad.

Tema 1. Tema 2. Informática Haskell Matemáticas Curso Pepe Gallardo Universidad de Málaga

Divisibilidad y congruencia

Guía 2: Funciones, listas, recursión e inducción

Programación declarativa ( )

ALPII Práctica 3. Bernardo García Fuentes

Tema 1: Programación Funcional

Programación Funcional

Introducción a los Algoritmos Tipos, Funciones y Patrones

Tema 4: Redes semánticas y marcos

Lógica y Programación

Tema 6. Definiciones de tipos

Polinomios. Taller de Álgebra I. Segundo cuatrimestre de 2013

Algoritmos y programas. Algoritmos y Estructuras de Datos I

Programación Declarativa Ejercicios de programación con listas

Introducción a la Matemática Discreta

1.1 Define un operador ( ) que devuelva True si y solo si tan solo uno de sus argumentos es True. Por ejemplo:? (3 > 2) (2 > 5)

Lógica matemática y fundamentos ( )

Lógica y Programación

Introducción a la programación funcional

Programación Declarativa UNIVERSIDAD DE MÁLAGA

Guía 1: Funciones, precedencia y tipado

Trabajo Práctico 1 - Programación Funcional Fecha de entrega: Jueves 20 de abril, hasta las 21 hs.

Programación lógica ( )

Polinomios. Taller de Álgebra I. Verano 2017

Guía 2: Funciones, listas, recursión e inducción

INGENIERÍA EN COMPUTACIÓN. INGENIERÍA EN COMPUTACIÓN División Departamento Licenciatura

LP - Lenguajes de Programación

4.3 Recursión en Scheme

Tema 5.- Tipos de datos compuestos

UNIVERSIDAD DISTRITAL FRANCISCO JOSÉ DE CALDAS

(Traductor de Lógico a Funcional)

Tema 3: Técnicas básicas de búsqueda para la resolución de problemas

Introducción a Haskell. El lenguaje Haskell

Tipos y estructuras de datos en los lenguajes funcionales

Test de primalidad probabiĺıstico

Transcripción:

Tema 6: Funciones recursivas Programación declarativa (2009 10) José A. Alonso Jiménez Grupo de Lógica Computacional Departamento de Ciencias de la Computación e I.A. Universidad de Sevilla Tema 6: Funciones recursivas 1. Recursión numérica 2. Recusión sobre lista 3. Recursión sobre varios argumentos 4. Recursión múltiple 5. Recursión mutua 6. 2 / 30

Recursión numérica Tema 6: Funciones recursivas 1. Recursión numérica 2. Recusión sobre lista 3. Recursión sobre varios argumentos 4. Recursión múltiple 5. Recursión mutua 6. 3 / 30 Recursión numérica Recursión numérica: El factorial La función factorial: factorial :: Integer -> Integer factorial 0 = 1 factorial (n + 1) = (n + 1) * factorial n factorial 3 = 3 * (factorial 2) = 3 * (2 * (factorial 1)) = 3 * (2 * (1 * (factorial 0))) = 3 * (2 * (1 * 1)) = 3 * (2 * 1) = 3 * 2 = 6 4 / 30

Recursión numérica Recursión numérica: El producto Definición recursiva del producto: por :: Int -> Int -> Int m `por` 0 = 0 m `por` (n + 1) = m + (m `por` n) 3 `por` 2 = 3 + (3 `por` 1) = 3 + (3 + (3 `por` 0)) = 3 + (3 + 0) = 3 + 3 = 6 5 / 30 Recusión sobre lista Tema 6: Funciones recursivas 1. Recursión numérica 2. Recusión sobre lista 3. Recursión sobre varios argumentos 4. Recursión múltiple 5. Recursión mutua 6. 6 / 30

Recusión sobre lista Recursión sobre listas: La función product Producto de una lista de números: Prelude product :: Num a => [a] -> a product [] = 1 product (n:ns) = n * product ns product [7,5,2] = 7 * (product [5,2]) = 7 * (5 * (product [2])) = 7 * (5 * (2 * (product []))) = 7 * (5 * (2 * 1)) = 7 * (5 * 2) = 7 * 10 = 70 7 / 30 Recusión sobre lista Recursión sobre listas: La función length Longitud de una lista: Prelude length :: [a] -> Int length [] = 0 length (_:xs) = 1 + length xs length [2,3,5] = 1 + (length [3,5]) = 1 + (1 + (length [5])) = 1 + (1 + (1 + (length []))) = 1 + (1 + (1 + 0)) = 1 + (1 + 1) = 1 + 2 = 3 8 / 30

Recusión sobre lista Recursión sobre listas: La función reverse Inversa de una lista: Prelude reverse :: [a] -> [a] reverse [] = [] reverse (x:xs) = reverse xs ++ [x] reverse [2,5,3] = (reverse [5,3]) ++ [2] = ((reverse [3]) ++ [5]) ++ [2] = (((reverse []) ++ [3]) ++ [5]) ++ [2] = (([] ++ [3]) ++ [5]) ++ [2] = ([3] ++ [5]) ++ [2] = [3,5] ++ [2] = [3,5,2] Recusión sobre lista 9 / 30 Recursión sobre listas: ++ Concatenación de listas: Prelude (++) :: [a] -> [a] -> [a] [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) [1,3,5] ++ [2,4] = 1:([3,5] ++ [2,4]) = 1:(3:([5] ++ [2,4])) = 1:(3:(5:([] ++ [2,4]))) = 1:(3:(5:[2,4])) = 1:(3:[5,2,4]) = 1:[3,5,2,4] = [1,3,5,2,4] 10 / 30

Recusión sobre lista Recursión sobre listas: Inserción ordenada (inserta e xs) inserta el elemento e en la lista xs delante del primer elemento de xs mayor o igual que e. Por ejemplo, inserta 5 [2,4,7,3,6,8,10] [2,4,5,7,3,6,8,10] inserta :: Ord a => a -> [a] -> [a] inserta e [] = [e] inserta e (x:xs) e <= x = e : (x:xs) otherwise = x : inserta e xs inserta 4 [1,3,5,7] = 1:(inserta 4 [3,5,7]) = 1:(3:(inserta 4 [5,7])) = 1:(3:(4:(5:[7]))) = 1:(3:(4:[5,7])) = [1,3,4,5,7] Recusión sobre lista 11 / 30 Recursión sobre listas: Ordenación por inserción (ordena_por_insercion xs) es la lista xs ordenada mediante inserción, Por ejemplo, ordena_por_insercion [2,4,3,6,3] [2,3,3,4,6] ordena_por_insercion :: Ord a => [a] -> [a] ordena_por_insercion [] = [] ordena_por_insercion (x:xs) = inserta x (ordena_por_insercion xs) ordena_por_insercion [7,9,6] = = inserta 7 (inserta 9 (inserta 6 [])) = inserta 7 (inserta 9 [6]) = inserta 7 [6,9] = [6,7,9] 12 / 30

Recursión sobre varios argumentos Tema 6: Funciones recursivas 1. Recursión numérica 2. Recusión sobre lista 3. Recursión sobre varios argumentos 4. Recursión múltiple 5. Recursión mutua 6. 13 / 30 Recursión sobre varios argumentos Recursión sobre varios argumentos: La función zip Emparejamiento de elementos: Prelude zip :: [a] -> [b] -> [(a, b)] zip [] _ = [] zip _ [] = [] zip (x:xs) (y:ys) = (x,y) : zip xs ys zip [1,3,5] [2,4,6,8] = (1,2) : (zip [3,5] [4,6,8]) = (1,2) : ((3,4) : (zip [5] [6,8])) = (1,2) : ((3,4) : ((5,6) : (zip [] [8]))) = (1,2) : ((3,4) : ((5,6) : [])) = [(1,2),(3,4),(5,6)] 14 / 30

Recursión sobre varios argumentos Recursión sobre varios argumentos: La función drop Eliminación de elementos iniciales: Prelude drop :: Int -> [a] -> [a] drop 0 xs = xs drop (n+1) [] = [] drop (n+1) (x:xs) = drop n xs drop 2 [5,7,9,4] drop 5 [1,4] = drop 1 [7,9,4] = drop 4 [4] = drop 0 [9,4] = drop 1 [] = [9,4] = [] 15 / 30 Recursión múltiple Tema 6: Funciones recursivas 1. Recursión numérica 2. Recusión sobre lista 3. Recursión sobre varios argumentos 4. Recursión múltiple 5. Recursión mutua 6. 16 / 30

Recursión múltiple Recursión múltiple: La función de Fibonacci La sucesión de Fibonacci es: 0,1,1,2,3,5,8,13,21,.... Sus dos primeros términos son 0 y 1 y los restantes se obtienen sumando los dos anteriores. (fibonacci n) es el n ésimo término de la sucesión de Fibonacci. Por ejemplo, fibonacci 8 21 fibonacci :: Int -> Int fibonacci 0 = 0 fibonacci 1 = 1 fibonacci (n+2) = fibonacci n + fibonacci (n+1) 17 / 30 Recursión múltiple Recursión múltiple: Ordenación rápida Algoritmo de ordenación rápida: ordena :: (Ord a) => [a] -> [a] ordena [] = [] ordena (x:xs) = (ordena menores) ++ [x] ++ (ordena mayores) where menores = [a a <- xs, a <= x] mayores = [b b <- xs, b > x] 18 / 30

Recursión mutua Tema 6: Funciones recursivas 1. Recursión numérica 2. Recusión sobre lista 3. Recursión sobre varios argumentos 4. Recursión múltiple 5. Recursión mutua 6. 19 / 30 Recursión mutua Recursión mutua: Par e impar Par e impar por recursión mutua: par :: Int -> Bool par 0 = True par (n+1) = impar n impar :: Int -> Bool impar 0 = False impar (n+1) = par n impar 3 par 3 = par 2 = impar 2 = impar 1 = par 1 = par 0 = impar 0 = True = False 20 / 30

Recursión mutua Recursión mutua: Posiciones pares e impares (pares xs) son los elementos de xs que ocupan posiciones pares. (impares xs) son los elementos de xs que ocupan posiciones impares. pares :: [a] -> [a] pares [] = [] pares (x:xs) = x : impares xs impares :: [a] -> [a] impares [] = [] impares (_:xs) = pares xs pares [1,3,5,7] = 1:(impares [3,5,7]) = 1:(pares [5,7]) = 1:(5:(impares [7])) = 1:(5:[]) = [1,5] 21 / 30 Tema 6: Funciones recursivas 1. Recursión numérica 2. Recusión sobre lista 3. Recursión sobre varios argumentos 4. Recursión múltiple 5. Recursión mutua 6. 22 / 30

Aplicación del método: La función product Paso 1: Definir el tipo: product :: [Int] -> Int Paso 2: Enumerar los casos: product :: [Int] -> Int product [] = product (n:ns) = Paso 3: Definir los casos simples: product :: [Int] -> Int product [] = 1 product (n:ns) = 23 / 30 Aplicación del método: La función product Paso 4: Definir los otros casos: product :: [Int] -> Int product [] = 1 product (n:ns) = n * product ns Paso 5: Generalizar y simplificar: product :: Num a => [a] -> a product = foldr (*) 1 donde (foldr op e l) pliega por la derecha la lista l colocando el operador op entre sus elementos y el elemento e al final. Por ejemplo, foldr (+) 6 [2,3,5] 2+(3+(5+6)) 16 foldr (-) 6 [2,3,5] 2-(3-(5-6)) -2 24 / 30

Aplicación del método: La función drop Paso 1: Definir el tipo: drop :: Int -> [a] -> [a] Paso 2: Enumerar los casos: drop :: Int -> [a] -> [a] drop 0 [] = drop 0 (x:xs) = drop (n+1) [] = drop (n+1) (x:xs) = 25 / 30 Aplicación del método: La función drop Paso 3: Definir los casos simples: drop :: Int -> [a] -> [a] drop 0 [] = [] drop 0 (x:xs) = x:xs drop (n+1) [] = [] drop (n+1) (x:xs) = Paso 4: Definir los otros casos: drop :: Int -> [a] -> [a] drop 0 [] = [] drop 0 (x:xs) = x:xs drop (n+1) [] = [] drop (n+1) (x:xs) = drop n xs 26 / 30

Aplicación del método: La función drop Paso 5: Generalizar y simplificar: drop :: Integral b => b -> [a] -> [a] drop 0 xs = xs drop (n+1) [] = [] drop (n+1) (_:xs) = drop n xs 27 / 30 Aplicación del método: La función init init elimina el último elemento de una lista no vacía. Paso 1: Definir el tipo: init :: [a] -> [a] Paso 2: Enumerar los casos: init :: [a] -> [a] init (x:xs) = Paso 3: Definir los casos simples: init :: [a] -> [a] init (x:xs) null xs = [] otherwise = 28 / 30

Aplicación del método: La función init Paso 4: Definir los otros casos: init :: [a] -> [a] init (x:xs) null xs = [] otherwise = x : init xs Paso 5: Generalizar y simplificar: init :: [a] -> [a] init [_] = [] init (x:xs) = x : init xs 29 / 30 Bibliografía Bibliografía 1. R. Bird. Introducción a la programación funcional con Haskell. Prentice Hall, 2000. Cap. 3: Números. Cap. 4: Listas. 2. G. Hutton Programming in Haskell. Cambridge University Press, 2007. Cap. 6: Recursive functions. 3. B. O Sullivan, D. Stewart y J. Goerzen Real World Haskell. O Reilly, 2008. Cap. 2: Types and Functions. 4. B.C. Ruiz, F. Gutiérrez, P. Guerrero y J.E. Gallardo. Razonando con Haskell. Thompson, 2004. Cap. 2: Introducción a Haskell. Cap. 6: Programación con listas. 5. S. Thompson. Haskell: The Craft of Functional Programming, Second Edition. Addison-Wesley, 1999. Cap. 4: Designing and writing programs. 30 / 30