1. Programación Funcional
Haskell
Elementos de Haskell
Programación Funcional en Haskell
Lenguajes de Programación
René Mac Kinney Romero
UAM - Iztapalapa
18 de Enero de 2012
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
2. Programación Funcional
Haskell
Elementos de Haskell
Resumen
Programación Funcional
Filosofía
Modelo de reescritura
Haskell
Denición de funciones
Interprete de Haskell
Listas y tipos
Reescritura
Elementos de Haskell
Estructuras de control
Comentarios
Fuertemente tipicado
Preludio y Ejemplos
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
3. Programación Funcional Filosofía
Haskell Modelo de reescritura
Elementos de Haskell
Resumen
Programación Funcional
Haskell
Elementos de Haskell
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
4. Programación Funcional Filosofía
Haskell Modelo de reescritura
Elementos de Haskell
Resumen
Programación Funcional
Filosofía
Modelo de reescritura
Haskell
Elementos de Haskell
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
5. Programación Funcional Filosofía
Haskell Modelo de reescritura
Elementos de Haskell
Otra forma de proponer la computación
Basada en el Calculo Lambda de Church y Kleene
Toda expresión computable se puede expresar como expresión
λ
Se caracteriza por programar con valores, funciones y formas
funcionales.
Es declarativo, se describe como son las funciones y no como
calcularlas.
Para calcular el valor de las funciones se utiliza el modelo de la
reducción β (β -redex)
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
6. Programación Funcional Filosofía
Haskell Modelo de reescritura
Elementos de Haskell
Resumen
Programación Funcional
Filosofía
Modelo de reescritura
Haskell
Elementos de Haskell
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
7. Programación Funcional Filosofía
Haskell Modelo de reescritura
Elementos de Haskell
No importa el orden en que se evalúe una función, siempre se
obtiene el mismo resultado.
Es decir que podemos evaluar una expresión en cualquier orden y
siempre obtendremos el mismo resultado. Dadas
f (x ) =x ∗x +2
g (y ) =y +y
f (g (5)) = g (5) ∗ g (5) + 2 = 10 ∗ 10 + 2 = 102
= f (5 + 5) = f (10) = 10 ∗ 10 + 2 = 102
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
8. Programación Funcional Denición de funciones
Haskell Interprete de Haskell
Elementos de Haskell Listas y tipos
Reescritura
Resumen
Programación Funcional
Haskell
Elementos de Haskell
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
9. Programación Funcional Denición de funciones
Haskell Interprete de Haskell
Elementos de Haskell Listas y tipos
Reescritura
Haskell Lenguaje funcional.
Hugs Interprete que calcula formas normales.
GHC Compilador de Haskell
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
10. Programación Funcional Denición de funciones
Haskell Interprete de Haskell
Elementos de Haskell Listas y tipos
Reescritura
Resumen
Programación Funcional
Haskell
Denición de funciones
Interprete de Haskell
Listas y tipos
Reescritura
Elementos de Haskell
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
11. Programación Funcional Denición de funciones
Haskell Interprete de Haskell
Elementos de Haskell Listas y tipos
Reescritura
La denición de las siguientes funciones
f x =x +2
fact (n) = n × fact (n − 1)
fact (0) =1
se hace en Haskell de la siguiente manera
f x = x + 2
fact (n) = n * fact (n-1)
fact (0) = 1
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
12. Programación Funcional Denición de funciones
Haskell Interprete de Haskell
Elementos de Haskell Listas y tipos
Reescritura
La función tiene que ir en la primera columna. Si la función ocupa
más de un renglón debe tener sangría a partir del segundo renglón.
fact (n) =
n * fact (n-1)
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
13. Programación Funcional Denición de funciones
Haskell Interprete de Haskell
Elementos de Haskell Listas y tipos
Reescritura
Resumen
Programación Funcional
Haskell
Denición de funciones
Interprete de Haskell
Listas y tipos
Reescritura
Elementos de Haskell
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
14. Programación Funcional Denición de funciones
Haskell Interprete de Haskell
Elementos de Haskell Listas y tipos
Reescritura
/em prelude_ ← cosas a evaluar
prelude 5+5
10 ⇒ Da resultado
prelude 23423*76342
1788158666 ⇒ Es el resultado
prelude :? ← ayuda
prelude x - x*3+sin(x)
ERROR - Cannot find showfunction for:
*** Expression : x - x * 3 + sin x
*** Of type : Double - Double ⇒ Da resultado
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
15. Programación Funcional Denición de funciones
Haskell Interprete de Haskell
Elementos de Haskell Listas y tipos
Reescritura
prelude (x - x*3+sin(x)) 4
11.2431975046921 ⇒ Es el resultado
prelude let f = (x - sin(x∧2)) in f 4
-0.287903316665065 ⇒ Es el resultado
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
16. Programación Funcional Denición de funciones
Haskell Interprete de Haskell
Elementos de Haskell Listas y tipos
Reescritura
Resumen
Programación Funcional
Haskell
Denición de funciones
Interprete de Haskell
Listas y tipos
Reescritura
Elementos de Haskell
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
17. Programación Funcional Denición de funciones
Haskell Interprete de Haskell
Elementos de Haskell Listas y tipos
Reescritura
Haskell es fuertemente tipicado y podemos utilizar los siguientes
tipos básicos:
Tipo Nombre Ejemplo
Int entero 5
Fractional fracciones 3/4
Float otante 3.141592
(a,b) tuplas (1,2)
Char caracter 'a'
[Char] cadena Hola
(que es una lista de caracteres 'H' 'o' 'l' 'a')
Para saber el tipo de una expresión: :type [1,2] ⇒ Tipo de la
expresión
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
18. Programación Funcional Denición de funciones
Haskell Interprete de Haskell
Elementos de Haskell Listas y tipos
Reescritura
Las listas se representan mediante la notación de corchetes.
La lista
[1, 2, 3, 4, 5]
es de tipo [Int]
La lista
[1, 2, a , b ]
es inválida porque no existe un tipo que se le pueda asignar.
Una lista también se puede representar utilizando el constructor : ,
por ejemplo
[1, 2, 3, 4, 5] ≡ 1 : 2 : 3 : 4 : 5 : []
La lista [] es la lista vacía.
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
19. Programación Funcional Denición de funciones
Haskell Interprete de Haskell
Elementos de Haskell Listas y tipos
Reescritura
Ejemplo
La siguiente función regresa la longitud de una lista
longitud [] = 0
longitud (x:xs) = 1 + longitud xs
Ejemplo
La siguiente función concatena dos listas
(++) [] (x:xs) = (x:xs)
(++) (y:ys) (x:xs) = y:(ys ++ (x:xs))
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
20. Programación Funcional Denición de funciones
Haskell Interprete de Haskell
Elementos de Haskell Listas y tipos
Reescritura
Resumen
Programación Funcional
Haskell
Denición de funciones
Interprete de Haskell
Listas y tipos
Reescritura
Elementos de Haskell
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
21. Programación Funcional Denición de funciones
Haskell Interprete de Haskell
Elementos de Haskell Listas y tipos
Reescritura
Ejemplo
Con reescritura obtenemos el valor de una función
Obtener la longitud de la lista [1,2,3].
longitud [1,2,3] = 1 + longitud [2,3]
= 1 + (1 + longitud [3])
= 1 + (1 + (1 + longitud []))
= 1 + (1 + (1 + 0)) = 3
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
23. Programación Funcional Denición de funciones
Haskell Interprete de Haskell
Elementos de Haskell Listas y tipos
Reescritura
Notas
Siempre se debe obtener el mismo resultado, no importando el
camino.
La forma en que una expresión esta completamente reducida (es
decir ya no se puede reescribir) se llama forma normal.
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
24. Programación Funcional Estructuras de control
Haskell Comentarios
Elementos de Haskell Fuertemente tipicado
Preludio y Ejemplos
Resumen
Programación Funcional
Haskell
Elementos de Haskell
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
25. Programación Funcional Estructuras de control
Haskell Comentarios
Elementos de Haskell Fuertemente tipicado
Preludio y Ejemplos
Resumen
Programación Funcional
Haskell
Elementos de Haskell
Estructuras de control
Comentarios
Fuertemente tipicado
Preludio y Ejemplos
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
26. Programación Funcional Estructuras de control
Haskell Comentarios
Elementos de Haskell Fuertemente tipicado
Preludio y Ejemplos
No hay estructuras de control, pero si existe la función especial if -
then - else .
Ejemplo
Utilización de la función if-then-else en Haskell.
f x = if x 2 then 0 else 1
g y = if y 0 then 3
Nota: La construcción del if-then no tiene sentido, ya que siempre
debe haber algo con lo cual se pueda reescribir
g (−1)
no tiene con que reescribirse.
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
27. Programación Funcional Estructuras de control
Haskell Comentarios
Elementos de Haskell Fuertemente tipicado
Preludio y Ejemplos
Resumen
Programación Funcional
Haskell
Elementos de Haskell
Estructuras de control
Comentarios
Fuertemente tipicado
Preludio y Ejemplos
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
28. Programación Funcional Estructuras de control
Haskell Comentarios
Elementos de Haskell Fuertemente tipicado
Preludio y Ejemplos
Para comentarios se utilizan dos guiones seguidos.
-- comentario
f x = x*x -- esta función calcula el cuadrado de un número
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
29. Programación Funcional Estructuras de control
Haskell Comentarios
Elementos de Haskell Fuertemente tipicado
Preludio y Ejemplos
Resumen
Programación Funcional
Haskell
Elementos de Haskell
Estructuras de control
Comentarios
Fuertemente tipicado
Preludio y Ejemplos
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
30. Programación Funcional Estructuras de control
Haskell Comentarios
Elementos de Haskell Fuertemente tipicado
Preludio y Ejemplos
Haskell es fuertemente tipicado y en la mayoría de veces el
intérprete o el compilador son capaces de inferir el tipo de la
función.
g x = x `mod` 3
1
El tipo inferido es
g :: Integral a = a - a
para expresar en Haskell un tipo se utiliza:
g :: Tipo - Tipo
1
Es decir que a es de un tipo Integral y g toma un parámetro de tipo a y
regresa un resultado de tipo a
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
31. Programación Funcional Estructuras de control
Haskell Comentarios
Elementos de Haskell Fuertemente tipicado
Preludio y Ejemplos
Resumen
Programación Funcional
Haskell
Elementos de Haskell
Estructuras de control
Comentarios
Fuertemente tipicado
Preludio y Ejemplos
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
32. Programación Funcional Estructuras de control
Haskell Comentarios
Elementos de Haskell Fuertemente tipicado
Preludio y Ejemplos
El prelude (preludio) dene la biblioteca básica de funciones, entre
ellas encontramos:
head lista Regresa la cabeza de la lista.
tail lista Regresa el resto de la lista (todos menos la cabeza).
elemento lista Función constructor de la lista.
zip lista1 lista2 Hace tuplas con los elementos de lista1 y lista2.
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
33. Programación Funcional Estructuras de control
Haskell Comentarios
Elementos de Haskell Fuertemente tipicado
Preludio y Ejemplos
Ejemplo
Ejemplos Preludio
prelude head [1,2,3]
1 ⇒ cabeza de la lista.
prelude tail [1,2,3]
[2,3] ⇒ lista sin primer elemento.
prelude zip [] [1,2,3]
[] ⇒ lista vacia.
prelude zip [1,2,3] [5,6,7]
[(1,5),(2,6),(3,7)] ⇒ lista de zip.
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
34. Programación Funcional Estructuras de control
Haskell Comentarios
Elementos de Haskell Fuertemente tipicado
Preludio y Ejemplos
Mas Ejemplos Preludio
Podemos denir:
len l = if l == [] then 0
else 1 + (len tail l)
usando el else
Ejemplo
Obtener la longitud de la lista [1, 2, 3].
1 + (len[2,3]) = 1+ (1+ len [3])
=1+(1+(1+ len []))
=1+(1+(1+0))
=3
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
35. Programación Funcional Estructuras de control
Haskell Comentarios
Elementos de Haskell Fuertemente tipicado
Preludio y Ejemplos
Lo usual es usar la función cons (:) con la que podemos escribir
listas como x : xs
len [] = 0
len (x :xs )= ... mínimo un término.
Donde x es la cabeza de la lista y xs es el cuerpo.
El apareamiento con el lado izquierdo de la ecuación debe ser único.
⇒ len (x :xs ) = 1 + len xs
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
36. Programación Funcional Estructuras de control
Haskell Comentarios
Elementos de Haskell Fuertemente tipicado
Preludio y Ejemplos
Quicksort
Ejemplo
Quicksort
quicksort (x:xs) = (quicksort (less x xs))
++ [x] ++ (quicksort (more x xs))
less x [] = []
less x (y:ys) = if (x y) then
y:(less x ys)
else
(less x ys)
more x [] = []
more x (y:ys) = if (x y) then
y:(more x ys)
else
(more x ys)
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
37. Programación Funcional Estructuras de control
Haskell Comentarios
Elementos de Haskell Fuertemente tipicado
Preludio y Ejemplos
Mas ejemplos
Ejemplo
Función para sumar una lista de enteros.
sum [] = 0
sum x:xs = x + sum xs
Ejemplo
Función que suma las coordenadas x de una lista de coordenadas
sumcx [] = 0
sumcx (s:ss)= x + sumcx ss
where (x,y) = s
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell
38. Programación Funcional Estructuras de control
Haskell Comentarios
Elementos de Haskell Fuertemente tipicado
Preludio y Ejemplos
Ejemplo
Invierte cadena.
inv [] = []
inv (x:xs) = inv xs ++ [x]
inv [1, 2, 3] 1/x , [2, 3]/xs
inv [2, 3] ++ [1]
inv [3] ++ [2] ++ [1]
inv [] ++ [3] ++ [2] ++ [1]
⇒ [3 , 2 , 1 ]
LP 12I - René Mac Kinney Romero Programación Funcional en Haskell