4-PP 4.2 - Prop PF + Haskell
4-PP 4.2 - Prop PF + Haskell
4-PP 4.2 - Prop PF + Haskell
Funcional
Características
Paradigmas de Programación - 2022
5 * doble 3
5 * ( 3 + 3 ) { por el operador + }
5 * 6 { por el operador * }
30
Cuando una expresión no posee redex, se dice que esta en forma normal.
Ordenes de reducción
Impaciente
• Se reduce siempre el término MAS INTERNO (el más anidado en la
expresión).
• En caso de que existan varios términos a reducir (con la misma
profundidad) se selecciona el que aparece más a la izquierda de la
expresión.
• Esto también se llama paso de parámetros por valor (call by value)
Impaciente Perezoso
Haskell's type
system allows us to
think at a very
abstract level: it
permits us to write
concise, powerful Strong Static Inferred
programs.
Inferencia de Tipos
Ejemplos:
par n = (n ´mod´ 2 = 0)
Como el operador mod es del tipo Integer -> Integer -> Integer, n
debe ser de tipo entero. Luego el cuerpo de la función será Boolean. Finalmente
se infiere que la función par es del tipo par :: Integer -> Boolean.
id n = n
Como no hay pistas suficientes del tipo de n, podemos asumir que es de tipo a,
en esas condiciones el tipo de id será polimórfico… id :: a -> a
Polimorfismo de Parámetros
Una función puede recibir parámetros de diferentes tipos; operará
uniformemente sobe cualquiera de ellos.
Ejemplos
http://book.realworldhaskell.org/read/
http://www.lcc.uma.es/~blas/pfHaskell/gentle/index.html
http://aprendehaskell.es/main.html
• Haskell Reference
http://zvon.org/other/haskell/Outputglobal/index.html
• Standard Prelude
https://www.haskell.org/onlinereport/standard-prelude.html
Intérprete Haskell
:type (^)
(^) :: (Num a, Integral b) => a -> b -> a
Programas en Haskell
Int (enteros)
Integer (enteros con precisión ilimitada)
Char (caracteres)
[Integer] (lista homogénea de enteros)
Integer->Integer (funciones que aplican Integer sobre Integer)
(Char, Double) (tupla formado por un carácter y un flotante)
• 5 :: Integer
• 'a' :: Char
• inc :: Integer -> Integer
• [1,2,3] :: [Integer]
• ('b',4) :: (Char,Integer)
Sinónimos de Tipos
True
False
x op y
infixr 2 ||
infixr 3 &&
infix 4 ==, /=, <, <=, >=, >
infixr 5 ++, :
infixl 6 +, -
infix 7 /, `div`, `rem`, `mod`
infixl 7 *
infixr 8 ^
Operadores y funciones prefijas
Esto significa que podemos usar las funciones polimórficas sobre listas
para operar con cadenas (strings). Por ejemplo:
• Recursión lineal
• Recursión de Cola
• Recursión de cola
4 * (let a = 9 in a + 1) + 2
calcBmis xs =
[bmi | (w, h) <- xs, let bmi = w / h ^ 2, bmi >= 25.0]
Expresiones case
Se toma una expresión y se reduce a determinados bloques en función al
emparejamiento de patrones que se realiza.
case expresion of
patrón -> resultado
patrón -> resultado
patrón -> resultado
...
La lista [1,2,3]
es realmente una abreviatura de la lista 1:(2:(3:[]))
Secuencia Infinita
[5..] => [5,6,7,8,9,10,11, ... ]
Listas aritméticas II
[LimInf,Salto..LimSup]
Ejemplos
[2,4..20] => [2,4,6,8,10,12,14,16,18,20]
length take
null drop
reverse sum
Manos a la obra
Intuitivamente, esta expresión puede leerse como "la lista de todos las
exp tales que x pertenece a xs y cumplen las condiciones de guarda”
[f x | x<-xs] = map f xs
[f x | x<-xs, p x] = map f (filter p xs)
[f x y | x<-xs, y<-ys] = concat [[f x y | y<-ys] | x<-xs]
[2 | even 4] = [2]
[2 | 2>3] = []
[x+3 | x <- [1..4]] = [4,5,6,7]
[y | (3,y) <- [(3,2),(5,1),(3,5)]] = [2,5]
[x*x | x <- [1..10], even x] = [4,16,36,64,100]
[x*x | x <- [1..8], even (x+1)] = [1,9,25,49]
Ejemplos varios II
[(x,y) | x<-[1..2],y<-[1..2]] =[(1,1),(1,2),(2,1),(2,2)]
[x| x<-[1..3],y<-[1..2]] = [1,1,2,2,3,3]
[3*x| letx+2 = 4] = [6]
triang :: [Integer]
triang = 1 : zipWith (+) [2..] triang
Las lambdas son funciones anónimas que suelen ser usadas cuando necesitamos
una función una sola vez. Normalmente creamos funciones lambda con el único
propósito de pasarlas a funciones de orden superior.
\x -> cuerpo
\x -> \y -> cuerpo
\x y -> cuerpo
inc' :: Integer -> Integer
inc' = \x -> x + 1
Iteradores
Esquemas
funcionales
Generadores
Plegadores
Transformadores de estructuras
Transformadores de estructuras
Filtros
Iteradores
Esquemas
funcionales
Generadores
Plegadores
Transformadores de estructuras
Transformadores de estructuras
Filtros
Iteradores
Esquemas
funcionales
Generadores
Plegadores
Transformadores de estructuras
Transformadores de estructuras
Iterador map
Toma una función y dos listas y las aplica iteradamente la función entre los
elementos que están en la misma posición de las listas.
zipWith (++) ["Bart ", "Lisa ", "Maggie "] (replicate 3 "Simpson")
["Bart Simpson","Lisa Simpson","Maggie Simpson"]
Iterador until
Iteradores
Esquemas
funcionales
Generadores
Plegadores
Transformadores de estructuras
Iterador iterate
iterate (*2) 1
Iteradores
Esquemas
funcionales
Generadores
Plegadores
Transformadores de estructuras
Plegadores
Los pliegues se pueden utilizar para implementar cualquier función que
recorra una lista, elemento a elemento, y luego devuelvan un valor.
Son funciones de orden superior que sintetizan los esquemas recursivos que
se utilizan con las distintas estructuras recursivas.
Plegador foldr
Ejemplo:
foldl (\acc x -> x : acc) [] [1..5]
[5,4,3,2,1]
Plegadores scanl y scanr
scanl y scanr son como foldl y foldr, solo que devuelven todos
los acumuladores intermedios en forma de lista.
𝒇. 𝒈 = 𝒇 𝒈 𝒙
iter = x : iter
Múltiplos de 5
mult5 = 0 : map (+5) mult5
Potencias de 2
pot2 = 1 : map (*2) pot2
Factoriales de enteros
facts = 1 : zipWith (*) [1..] facts
Sucesión de Fibonacci
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
Extensión del ejemplo
Sucesión de Fibonacci
fibs= 1 : 1 : zipWith (+) fibs (tail fibs)
fibs = 1 : 1 : 2 : 3 : 5 : ...
𝑀 = (𝑄, 𝑆, 𝑃, 𝐼, 𝐹)
donde
• 𝑄 es el conjunto finito de estados
• 𝑆 es el alfabeto finito de entrada
Definición • 𝐼 ⊆ 𝑄 son los estados iniciales
• 𝐹 ⊆ 𝑄 son los estados finales
• 𝑃 ⊆ (𝑄 𝑥 𝑆 𝑥 𝑄) son la relación de transición de
M, toda vez que (𝑞, 𝑠, 𝑞′) sea un elemento de P,
luego 𝑞 → 𝑞´es una transición de M rotulado
por 𝑠.
Autómata finito no determinístico que
acepta el lenguaje:
L = { / ∈ {0, 1}* y contiene la
subcadena 00 ó x contiene la
subcadena 11}