Tipos y estructuras de datos en los lenguajes funcionales

Tipos y estructuras de datos en los lenguajes funcionales Salvador Lucas Alba Departamento de Sistemas Informáticos y Computación Universidad Politéc...
0 downloads 0 Views 411KB Size
Tipos y estructuras de datos en los lenguajes funcionales

Salvador Lucas Alba Departamento de Sistemas Informáticos y Computación Universidad Politécnica de Valencia http://www.dsic.upv.es/users/elp/slucas.html

Objetivos • Introducir los tipos de datos como componente fundamental del estilo funcional • Introducir los mecanismos de estructuración y abstracción de datos en los lenguajes funcionales • Presentar los tipos y estructuras de datos usuales en los lenguajes funcionales

Desarrollo 1. 2. 3. 4.

Tipos Tipos básicos y tipos numéricos Tipos algebraicos Tipos funcionales: orden superior, definición de funciones 5. Listas y árboles 6. Tipos abstractos de datos

Desarrollo 1. 2. 3. 4.

Tipos Tipos básicos y tipos numéricos Tipos algebraicos Tipos funcionales: orden superior, definición de funciones 5. Listas y árboles 6. Tipos abstractos de datos

Tipos Motivación • Evitar o detectar errores de programación Un tipo caracteriza el conjunto de valores que las expresiones de ese tipo pueden tener

• Ayudar a estructurar la información Los tipos pueden verse como colecciones de valores que comparten ciertas propiedades

• Ayudar a manejar estructuras de datos Los tipos indican cómo utilizar las estructuras de datos que comparten el mismo tipo

Tipos Lenguajes tipificados • Un tipo representa el conjunto de valores que puede adoptar una variable o expresión • En los lenguajes tipificados, las variables adoptan un tipo (ej. Pascal, Haskell) • Los lenguajes que no restringen el rango de valores que pueden adoptar las variables son no tipificados (ej. Lisp, Prolog)

Tipos Lenguajes tipificados En los lenguajes funcionales modernos todas las expresiones (y subexpresiones) tienen un tipo

Tipos Lenguajes tipificados • Los lenguajes tipificados incorporan un sistema de tipos que determina si los programas son legales • Los sistemas de tipos se utilizan para determinar si los programas tienen un comportamiento adecuado Errores manifiestos

1/0 1/0

Errores ocultos

Limites Limites vector vector

Tipos Lenguajes tipificados • Un lenguaje de programación es seguro (safe) si no son posibles errores ocultos • Los lenguajes pueden garantizar la seguridad mediante comprobaciones estáticas (static check, ej. ML, Haskell), o dinámicas (dynamic check, ej. Lisp) Compilación

Ejecución

Tipos Lenguajes tipificados • En algunos lenguajes tipificados, la simple comprobación estática de tipos puede hacerlos seguros (ej. ML, Haskell) • En otros casos, esto no es así (ej. Pascal, C)

Tipos Lenguajes tipificados El sistema de tipos de los lenguajes funcionales modernos garantiza la escritura de programas seguros

Tipos Lenguajes tipificados • En los lenguajes con tipificación explícita, los tipos forman parte de la sintaxis • En los lenguajes con tipificación implícita, los tipos no forman parte de la sintaxis Lenguajes Expresiones Sistema de = + tipificados de programa tipos

Tipos Lenguajes tipificados El sistema de tipos de los lenguajes funcionales modernos permite la tipificación implícita (debido a la posibilidad de inferencia de tipos)

Sistemas de tipos Expresiones de tipo • Los tipos se describen mediante un lenguaje de expresiones de tipo: – – – –

Tipos básicos o primitivos: Bool, Char, Int, ... Variables de tipo: a, b, c, ... Constructores de tipo: →, ×, [ ], ... Reglas de construcción de las expresiones: τ ::= Bool | Char | Int | ··· | t | τ → τ | τ × τ | [ τ ] | ···

Tipos Expresiones de tipo • Ejemplos:

Tipos básicos

• Bool, es el tipo de los valores booleanos True y Tipos False monomórficos • Int -> Int, es el tipo de la función fact, que devuelve el factorial de un número • [ a ] -> Int, es el tipo de la función length, que Tipos obtienen la longitud de una lista constituida por polimórficos elementos de cualquier tipo Variable de tipo

Constructores de tipo

Sistemas de tipos Asertos • Los sistemas de tipos permiten razonar sobre tipos y asociar expresiones de tipo con expresiones de programa: – Tipificación M :: τ – Equivalencia τ = τ’ τ [Int] el intérprete (que utiliza el algoritmo de Mycroft en ese caso) acepta la definición

Sistemas de tipos Problemas de tipificación • Ejemplo: consideremos la ecuación gx=g1 El algoritmo de Milner infiere el tipo g :: Num a => a -> b mientras que el algoritmo de Mycroft acepta la tipificación explícita (más general) g :: a -> b

Sistemas de tipos Problemas de tipificación A pesar de la posibilidad de tipificación implícita, a veces es recomendable dar los tipos de las funciones explícitamente

Polimorfismo Polimorfismo paramétrico • Los tipos en cuya expresión de tipo no aparecen variables de tipo se denominan monotipos o tipos monomórficos • Los tipos en cuya expresión de tipo aparecen variables se denominan politipos o tipos polimórficos (polimorfismo paramétrico) • Un tipo polimórfico representa un número infinito de monotipos

Polimorfismo Polimorfismo paramétrico • Ejemplo: la función length :: [a] -> Int puede verse como una función con infinitos monotipos [Int] -> Int, [Bool] -> Int, [Int -> Int] -> Int, ...

Polimorfismo Polimorfismo paramétrico • Ejemplo: La implementación de length :: [a] -> Int es única: length [ ] =0 length (x:xs) = 1+length xs y resulta válida para todos los usos de la función

Polimorfismo Polimorfismo paramétrico • Con un sistema de tipos polimórficos, el algoritmo de inferencia de tipos intenta obtener el tipo principal de las expresiones • El tipo principal es el tipo más general capaz de capturar todos los usos válidos de la expresión

Polimorfismo Polimorfismo paramétrico El sistema de tipos de Hindley-Milner asegura que toda expresión tipificable tiene un tipo principal único

Polimorfismo Sobrecarga • A veces nos interesa sobrecargar el uso de ciertos operadores, aplicándolos sobre argumentos de distintos tipos, aunque de forma limitada • Otras veces, no tiene sentido asignar un politipo a un operador si no podemos implementar todas sus concreciones

Polimorfismo Sobrecarga • Este tipo de polimorfismo se denomina polimorfismo ad-hoc o sobrecarga (overloading)

Polimorfismo Sobrecarga • Ejemplo: los operadores aritméticos (+), (-), (*), (/), ..., suelen estar sobrecargados: (+) :: Int -> Int -> Int (+) :: Float -> Float -> Float (+) :: Complex -> Complex -> Complex corresponden a distintos usos de (+). Otro: (+) :: Int -> Float -> Float

Polimorfismo Sobrecarga • El operador (+) no puede recibir el politipo (+) :: a -> a -> a porque implicaría dotar de significado a la ‘suma’ de caracteres, funciones, listas, etc., lo cual puede interesarnos o no

Polimorfismo Sobrecarga • Ejemplo: El operador de igualdad (==), aun teniendo una semántica bien definida, no es implementable en algunos casos. ¿Cómo determinar (efectivamente) si dos funciones son iguales?

Polimorfismo Sobrecarga • Matemáticamente: sean f:D→E

y

g:D→E

dos funciones. Tenemos que f =D → E g

si y sólo si

∀x∈D, f(x) =E f(x)

Si D es infinito, o f no es computable,

=D → E puede no ser decidible

Polimorfismo Sobrecarga • El operador (==) no puede recibir el politipo (==) :: a -> a -> Bool porque tendríamos que implementar la comprobación de igualdad para todos los tipos; en particular para las funciones: (==) :: (a->b) -> (a->b) -> Bool

Polimorfismo Sobrecarga En Haskell, el polimorfismo ad-hoc se implementa mediante el concepto de clase

Polimorfismo Sobrecarga • Una clase es una colección de tipos • Todos los tipos pertenecientes a una clase deben tener definidas ciertas operaciones

Polimorfismo Sobrecarga • Ejemplo: – Los miembros de la clase Eq deben definir las operaciones (==) y (/=) para comprobar si dos elementos son iguales o distintos – Los miembros de la clase Ord deben tener definidas, además de (==) y (/=), las relaciones ( Bool class Eq a => Ord a where -- simplificado (=) :: a -> a -> Bool Ord es una subclase de Eq

Polimorfismo Sobrecarga • De acuerdo con la declaración anterior, el tipo (sobrecargado) de (==) es (==) :: Eq a => a -> a -> Bool que se interpreta como sigue: si a es un tipo de la clase Eq, el tipo de (==) es a -> a -> Bool

Polimorfismo Sobrecarga • Algunas clases predefinidas de Haskell son: Eq: tipos con comprobación de igualdad Ord: tipos con operadores de comparación Enum: tipos cuyos valores son secuenciables Show: tipos cuyos valores son convertibles en cadenas de caracteres – Num, Integral, Fractional, Real, Floating, RealFrac, RealFloat: clases numéricas – – – –

Polimorfismo Sobrecarga • Es posible añadir nuevos tipos a una clase, si particularizamos las operaciones propias de ésta para los valores del nuevo tipo

Polimorfismo Sobrecarga • Ejemplo: consideremos el tipo data Nat = Cero | S Nat deriving Show Podemos añadirlo a la clase Eq: instance Eq Nat where Cero== Cero = True S n == S m = m == n _ == _ = False

Polimorfismo Sobrecarga • Ejemplo: En realidad, bastaría con escribir data Nat = Cero | S Nat deriving (Eq, Show)

Polimorfismo Sobrecarga • La clase Num se define como class (Eq a, Show a) => Num a where (+),(-),(*) :: a -> a -> a ¡¡Simplificado!!

Polimorfismo Sobrecarga • Podemos añadir el tipo Nat a la clase Num: instance Num Nat where No es preciso Cero + n = n definir todas (S n) + m = S (n+m) las operaciones Cero * n = Cero (¡¡pero no se podrán usar!!) (S n) * m = m + (n*m)

Polimorfismo Sobrecarga • Ahora podríamos escribir, directamente: fact Cero = S Cero fact (S n) = (S n) * fact n ¡¡Sobrecargado!!

Desarrollo 1. 2. 3. 4.

Tipos Tipos básicos y tipos numéricos Tipos algebraicos Tipos funcionales: orden superior, definición de funciones 5. Listas y árboles 6. Tipos abstractos de datos

Tipos básicos •

Los tipos básicos proporcionados por Haskell son: – – – – –

Booleanos Caracteres Tuplas Cadenas Tipos numéricos

Tipos básicos Booleanos • •

Los valores del tipo Bool son True y False El tipo Bool pertenece a las clases Bounded, Enum, Eq, Ord y Show, entre otras

Tipos básicos Booleanos •

El perfil de la clase Enum es: class Enum a where succ,pred :: a -> a toEnum :: Int -> a fromEnum :: a -> Int ¡¡Simplificado!!

Tipos básicos Booleanos •

Operaciones usuales para Bool (en Haskell): – Conjunción:&& :: Bool -> Bool -> Bool – Disyunción:| | :: Bool -> Bool -> Bool – Negación: not :: Bool -> Bool

Tipos básicos Caracteres •

Los valores del tipo Char son los caracteres: – – – – – –

‘a’, ‘b’, ..., ‘A’, ‘B’, ..., ‘1’, ‘2’, ... ‘\a’, ‘\b’, ‘\f’, ‘\n’, ‘\r’, ... ‘\BEL’, ‘\BS’, ‘\FF’, ‘\LF’, ‘\CR’, ... ‘\7’, ‘\8’, ‘\12’, ‘\10’, ‘\13’, ... ‘\o7’, ‘\o10’, ‘\o14’, ‘\o12’, ‘\o15’ ‘\x7’, ‘\x8’, ‘\xC’, ‘\xA’, ‘\xD’, ...

Tipos básicos Caracteres • •

El tipo Char pertenece a Bounded, Enum, Eq, Ord y Show Operaciones usuales para Char: – isAlpha, isAlphaNum, isAscii, isDigit, isLower, isPrint, isUpper :: Char -> Bool – toLower, toUpper :: Char -> Char – chr :: Int -> Char -- toEnum – ord :: Char -> Int -- fromEnum

Tipos básicos Tuplas •

El tipo polimórfico (a,b) (en general, (a1,..., an) ) permite agrupar valores procedentes de tipos distintos: (True,False) :: (Bool,Bool) (True,’a’) :: (Bool,Char) ((True,False),’a’) :: ((Bool,Bool),Char) (isDigit,’a’,1) :: (Char -> Bool, Char,Int)

Tipos básicos Tuplas • •

El tipo tupla pertenece a las clases Eq, Ord, Show y Enum, entre otras Operaciones usuales sobre tuplas: – Proyección izq: – Proyección der:

fst :: (a,b) -> a snd :: (a,b) -> b

¡¡Sólo con pares!!

Tipos básicos Cadenas •



Los valores del tipo String son las cadenas de caracteres: “”, “1&bA”, “Esta frase \10ocupa dos lineas” En realidad, String es un tipo sinónimo: type String = [Char]

Tipos básicos Cadenas •

El tipo String pertenece a las clases Eq, Ord y Show, entre otras

Tipos numéricos Números en Haskell •

Los tipos numéricos en Haskell son: – – – –

Int, Integer: Números enteros Float, Double: Números reales Ratio: Números racionales Complex: Números complejos

Preludio Estándar Librerías

Tipos numéricos Números enteros •

Los valores del tipo Int son los enteros de rango acotado: 0, 45, -3452, 2147493647

• •

El límite es maxBound :: Int El tipo Int pertenece a la clase Bounded class Bounded a where minBound :: a maxBound :: a

Tipos numéricos Números enteros •

El tipo Int también pertenece a las clases Enum, Eq, Ord y Show, además de a las clases numéricas Num, Real e Integral

Tipos numéricos Números enteros class (Eq a, Show a) => Num a where (+),(-),(*) :: a -> a -> a negate :: a -> a abs,signum :: a -> a fromInteger :: Integer -> a

Tipos numéricos Números enteros class (Num a, Ord a) => Real a where toRational :: a -> Rational class (Real a, Enum a) => Integral a where quot,rem,div,mod :: a -> a -> a quotRem, divMod :: a -> a -> (a,a) toInteger :: a -> Integer

Tipos numéricos Números enteros • •

Los valores del tipo Integer son los enteros de rango arbitrario La aritmética con Integer es más precisa que con Int, pero más costosa

Tipos numéricos Números enteros •

El tipo Integer pertenece a las clases Enum, Eq, Ord y Show (pero no a Bounded), además de a las clases numéricas Num, Real e Integral

Tipos numéricos Números reales •

Los valores del tipo Float son los números en coma flotante de precisión simple: 0.31426, -23.12, 567.347, 4523.0 231.61e7, 231.6e-2, -3.412e03

Tipos numéricos Números reales •

El tipo Float pertenece a las clases Enum, Eq, Ord y Show (no a Bounded), además de a las clases numéricas Num, Real, Fractional, Floating, RealFrac y RealFloat

Tipos numéricos Números reales class (Num a) => Fractional a where (/) :: a -> a -> a recip :: a -> a fromRational :: Rational -> a

Tipos numéricos Números reales class (Fractional a) => Floating a where pi :: a exp,log,sqrt :: a -> a (**),logBase :: a -> a -> a sin,cos,tan, asin,acos,atan, sinh,cosh,tanh, asinh,acosh,atanh :: a -> a

Tipos numéricos Números reales class (Real a,Fractional a) => RealFrac a where properFraction :: (Integral b) => a -> (b,a) truncate,round :: (Integral b) => a -> b ceiling,floor :: (Integral b) => a -> b

Tipos numéricos Números reales class (RealFrac a,Floating a) => RealFloat a where floatRadix :: a -> Integer floatDigits :: a -> Int floatRange :: a -> (Int,Int) decodeFloat :: a -> (Integer,Int) encodeFloat :: Integer -> Int -> a

Tipos numéricos Números reales class (RealFrac a,Floating a) => RealFloat a where -- Continuación exponent :: a -> Int significand :: a -> a scaleFloat :: Int -> a -> a isNaN,isInfinite:: a -> Bool isDenormalized:: a -> Bool isIEEE :: a -> Bool

Tipos numéricos Números reales Otras operaciones de interés son: (^) :: (Integral b, Num a) => a -> b -> a Potencia con exponente entero

(^^) :: (Integral b, Fractional a) => a -> b -> a Potencia con exponente racional

Tipos numéricos Números reales •



Los valores del tipo Double son los números en coma flotante de precisión doble El tipo Double pertenece a las mismas clases que Float

Tipos numéricos Números racionales y complejos •





Los tipos Ratio y Rational, para trabajar con números racionales, se definen en la librería Ratio de Haskell 98 El tipo Complex, para trabajar con números complejos, se definen en la librería Complex de Haskell 98 La librería Numeric de Haskell 98 describe funciones numéricas adicionales

Tipos numéricos Num Int,Integer,Float,Double

Real

Fractional

Int,Integer,Float,Double

Float,Double

Integral

RealFrac

Floating

Int,Integer

Float,Double

Float,Double

RealFloat Float,Double

Desarrollo 1. 2. 3. 4.

Tipos Tipos básicos y tipos numéricos Tipos algebraicos Tipos funcionales: orden superior, definición de funciones 5. Listas y árboles 6. Tipos abstractos de datos

Tipos Tipos algebraicos • Los tipos algebraicos se definen junto con los valores que éstos contienen • Ejemplos: • • • •

data Color = Red | Green | Blue data Laboral = Lu | Ma | Mi | Ju | Vi data TreeInt = L Int | B TreeInt TreeInt data Tree t = L t | B (Tree t) (Tree t)

Tipos Tipos algebraicos • Los tipos algebraicos se definen junto con los valores que éstos contienen • Ejemplos: • • • •

data Color = Red | Green | Blue data Laboral = Lu | Ma | Mi | Ju | Vi data TreeInt = L Int | B TreeInt TreeInt data Tree t = L t | B (Tree t) (Tree t) Constructores de tipos

Tipos Tipos algebraicos • Los tipos algebraicos se definen junto con los valores que éstos contienen • Ejemplos: • Simples • • Estructurados •

data Color = Red | Green | Blue data Laboral = Lu | Ma | Mi | Ju | Vi data TreeInt = L Int | B TreeInt TreeInt data Tree t = L t | B (Tree t) (Tree t) Constructores de datos

Tipos Tipos algebraicos • Los tipos algebraicos se definen junto con los valores que éstos contienen • Ejemplos: • • • •

data Color = Red | Green | Blue data Laboral = Lu | Ma | Mi | Ju | Vi data TreeInt = L Int | B TreeInt TreeInt data Tree t = L t | B (Tree t) (Tree t) Polimórfico

Variables de tipo

Tipos Tipos algebraicos • Los valores se obtienen considerando la definición de tipo como una gramática: – Los constructores de datos son símbolos terminales – Los constructores de tipo son símbolos no terminales

• Los valores del tipo son los términos del lenguaje generado por la gramática

Tipos Tipos algebraicos • Ejemplo: Int := 0 | 1 | 2 | 3 | ··· | -1 | -2 | -3 | ··· TreeInt := L Int | B TreeInt TreeInt

Valores de este tipo son: L 1, L -10, B (L 1) (L 10), B (B (L 1) (L1)) (L -1)

Tipos Tipos algebraicos • Ejemplo de valor del tipo TreeInt 1 4 2

3

(B (L 1) (B (B (L 2) (L 3)) (L 4)))

Tipos Tipos algebraicos • Las siguientes expresiones: L (1+1) B (B (L 1) (L (length “ab”))) (L (fact 2))

son del tipo TreeInt, pero no son valores (contienen símbolos no constructores)

Desarrollo 1. 2. 3. 4.

Tipos Tipos básicos y tipos numéricos Tipos algebraicos Tipos funcionales: orden superior, definición de funciones 5. Listas y árboles 6. Tipos abstractos de datos

Tipos funcionales • Los tipos funcionales (que involucran el constructor de tipo →) son muy importantes en programación funcional • Ejemplo: Int -> Int a -> Bool Num a => a -> a -> a (a -> b) -> [a] -> [b]

Tipos funcionales Valores funcionales • Los valores funcionales pueden especificarse de dos formas: – explícitamente: mediante expresiones lambda – implícitamente: mediante ecuaciones

Definición de funciones Expresiones lambda • Una función f se describe mediante una expresión lambda de la forma \ x1 · · · xk -> e

• Las variables x1, ..., xk son distintas entre sí y las únicas que aparecen en la expresión e

Definición de funciones Expresiones lambda • Ejemplo \ x y -> x+y \ x -> 2*x \ x -> True \ m n -> B (L m) (L n)

Definición de funciones Expresiones lambda La definición de funciones recursivas es problemática (¡aunque no imposible!)

Definición de funciones Ecuaciones • En los lenguajes funcionales, lo normal es definir las funciones mediante ecuaciones empleando (y combinando) distintas técnicas: – – – – –

parámetros formales guardas ajuste de patrones distinción de casos cláusulas where

Definición de funciones Parámetros formales • Una función f se describe mediante ecuaciones de la forma: f x1 · · · xk = r

• Las variables x1, ..., xk son distintas entre sí y las únicas que aparecen en la parte derecha r

Definición de funciones Parámetros formales • Ejemplos: doble x triple x seisveces x fact n

= x+x = 3*x = doble (triple x) = if n==0 then 1 else n*fact (n-1)

Definición de funciones Parámetros formales • Ejemplos: doble x = x + x triple x = 3 * x Funciones primitivas

Definición de funciones Parámetros formales • Ejemplos: doble x = x+x triple x = 3*x seisveces x = doble (triple x) Otras funciones de usuario

Definición de funciones Parámetros formales • Ejemplos: doble x = x+x triple x = 3*x seisveces x = doble (triple x) = if n==0 then 1 else fact n n*fact (n-1) Recursividad

Definición de funciones Parámetros formales y guardas • Una función f se describe mediante ecuaciones de la forma: f x1 · · · xk | c = r

donde c es una expresión booleana

Definición de funciones Parámetros formales y guardas • Ejemplos: fact n | | sign x | | |

n==0 = 1 n>0 = n*fact (n-1) x0 = pos

Definición de funciones Parámetros formales y guardas • Ejemplos: fact n | | sign x | | |

n==0 = 1 n>0 = n*fact (n-1) x0 = pos Guardas

Definición de funciones Ajuste de patrones • Una función f se describe mediante ecuaciones de la forma: f p1 · · · pk = r

• Los patrones p1, ..., pk son términos constituidos por constructores de datos y variables

Definición de funciones Ajuste de patrones • Ejemplos: length [] =0 length (x:xs) = 1+length xs data Nat = Cero | S Nat first Cero _ = [] first (S n) (x:xs) = x:(first n xs)

Definición de funciones Ajuste de patrones • Ejemplos: length [] =0 length (x:xs) = 1+length xs data Nat = Cero | S Nat first Cero _ = [] first (S n) (x:xs) = x:(first n xs) Patrones

Patrones

Definición de funciones Ajuste de patrones • Una expresión e se ajusta a un patrón p (pattern matching) si e puede verse como una concreción de p (dando ciertos valores a las variables libres de p)

Definición de funciones Ajuste de patrones • Ejemplo: la expresión S (S Cero) se ajusta al patrón S x pero no al patrón Cero S (S Cero) {x := S Cero}

Sx

S (S Cero) X Cero

Definición de funciones Ajuste de patrones El ajuste de patrones permite clasificar datos y explorar / recuperar subestructuras de los mismos

Definición de funciones Distinción de casos • Una función f se describe mediante ecuaciones de la forma: f p1 · · · pk = case x of q1 -> e1 ... qn -> en

• Donde p1 · · · pk, q1 · · · qn son patrones, x

es una variable y e1 · · · en expresiones

Definición de funciones Distinción de casos • Ejemplo: length xs = case xs of [ ] -> 0 (y:ys) -> 1+length ys

Definición de funciones Cláusulas where • Una función f se describe mediante ecuaciones de la forma: f p1 · · · pk = e where l1 = r1 ... ln = rn

• Donde l1 · · · ln son patrones o partes

izquierdas de definiciones de función, y r1 · · · rn son expresiones

Definición de funciones Cláusulas where • Ejemplo: raicesEc2 a b c = ((-b+d)/a’,(-b-d)/a’) where d = sqrt(b^2-4*a*c) a’ = 2*a

Orden superior Funciones como ciudadanos de primera clase • En programación funcional, las funciones son ‘ciudadanos de primera clase’ (first class citizens):

Orden superior Funciones como ciudadanos de primera clase • En programación funcional, las funciones son ‘ciudadanos de primera clase’ (first class citizens): – Pueden ser pasadas, como argumentos, a otras funciones

Orden superior Funciones como ciudadanos de primera clase • En programación funcional, las funciones son ‘ciudadanos de primera clase’ (first class citizens): – Pueden ser pasadas, como argumentos, a otras funciones – Pueden ser devueltas como resultado de una llamada a función

Orden superior Funciones como ciudadanos de primera clase map aplica una función f

• Ejemplos:

a cada elemento de una lista

map f [] = [] map f (x:xs) = (f x):map f xs add x y add2

= x+y = add 2 aplicación parcial

add2 añade 2 al número

que se le pasa como argumento

Orden superior Currificación • A cada función (sobre k-tuplas) f: D1 × D2 × ··· × Dk → E

le corresponde una función fC: D1 → (D2 → ( ··· → (Dk → E)···) que a cada valor de D1 le asocia una función de k-1 argumentos (y viceversa) • fC es la versión currificada de f

Orden superior Currificación • Ejemplo: map :: (a -> b) -> [a] -> [b] if :: Bool -> a -> a -> a + :: Num a => a -> a -> a

Orden superior Currificación • El operador -> es asociativo por la derecha a -> b -> c a -> (b -> c)

equivale a y difiere de (a -> b) -> c

• El operador de aplicación (a veces denotado como @) es asociativo por la izquierda f ab

equivale a (f a) b

y difiere de f (a b)

Orden superior Currificación • En programación funcional ésto facilita la aplicación parcial de una función: si f :: a -> b -> c

Entonces, si e::a, escribir fe

tiene sentido pleno: se trata de una función f e :: b -> c

Orden superior Currificación • Ejemplo: la expresión map add2 [1,2] es válida en un lenguaje como Haskell, y sería equivalente a map (add 2) [1,2] o incluso Sección map (+ 2) [1,2]

Desarrollo 1. 2. 3. 4.

Tipos Tipos básicos y tipos numéricos Tipos algebraicos Tipos funcionales: orden superior, definición de funciones 5. Listas y árboles 6. Tipos abstractos de datos

Bibliografía [Car97] L. Cardelli. Type Systems. [PE93] R. Plasmeijer and M. van Eekelen. Functional Programming and Parallel Graph Rewriting. AddisonWesley, Reading, MA, 1993 [Rea93] C. Reade. Elements of Functional Programming. Addison-Wesley, Reading, MA, 1993

λ

:=