Tipos y estructuras de datos en los lenguajes funcionales

134  Download (0)

Full text

(1)

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

(2)

Objetivos

Objetivos

• Introducir los tipos de datos como compo-nente fundamental del estilo funcional

• Introducir los mecanismos de estructura-ción y abstracción de datos en los lenguajes funcionales

• Presentar los tipos y estructuras de datos

(3)

Desarrollo

Desarrollo

1. Tipos

2. Tipos básicos y tipos numéricos 3. Tipos algebraicos

4. Tipos funcionales: orden superior, definición de funciones

5. Listas y árboles

(4)

Desarrollo

Desarrollo

1. Tipos

2. Tipos básicos y tipos numéricos 3. Tipos algebraicos

4. Tipos funcionales: orden superior, definición de funciones

5. Listas y árboles

(5)

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

(6)

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

(7)

Lenguajes tipificados

Tipos

Tipos

En los lenguajes funcionales modernos todas las expresiones (y subexpresiones)

(8)

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

Tipos

Tipos

Errores manifiestos Errores

ocultos Limites vector

Limites vector 1/0

(9)

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)

Tipos

Tipos

(10)

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

(11)

Lenguajes tipificados

Tipos

Tipos

El sistema de tipos de los lenguajes

funcionales modernos garantiza la escritura de programas seguros

(12)

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

Tipos

Tipos

Lenguajes tipificados = Expresiones de programa Sistema de tipos +

(13)

Lenguajes tipificados

Tipos

Tipos

El sistema de tipos de los lenguajes funcionales modernos permite la tipificación implícita

(14)

Expresiones de tipo

Sistemas de tipos

Sistemas de tipos

• 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:

(15)

Expresiones de tipo

Tipos

Tipos

Tipos monomórficos Tipos polimórficos Tipos básicos Constructores de tipo Variable de tipo • Ejemplos:

• Bool, es el tipo de los valores booleanos True y False

• 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 obtienen la longitud de una lista constituida por elementos de cualquier tipo

(16)

Asertos

Sistemas de tipos

Sistemas de tipos

• Los sistemas de tipos permiten razonar

sobre tipos y asociar expresiones de tipo con expresiones de programa:

– Tipificación M :: τ (M tiene tipo τ)

– Equivalencia τ = τ’ (τ y τ’ son equivalentes) – Subtipo τ<:τ’ (τ es un subtipo de τ’)

(17)

Sentencias

Sistemas de tipos

Sistemas de tipos

• Las sentencias sobre las que se razona en los sistemas de tipos son de la forma:

Γ Φ⊥ Contexto de tipificación Γ= ∅, x1::τ1, x2::τ2, ..., xn::τn para n≥0 Aserto

Con variables libres x1, x2, ..., xn

(18)

Sentencias

Sistemas de tipos

Sistemas de tipos

• Ejemplo: ∅ ⊥ True::Bool ∅, x::Int ⊥ x+1::Int

El tipo de True es Bool El tipo de x+1 es Int si el tipo de x es Int

(19)

Sistema formal

Sistemas de tipos

Sistemas de tipos

• Las reglas del sistema de tipos tienen la forma general:

Γ Φ⊥

Γ1 ⊥ Φ1 ... Γn ⊥ Φn (condiciones) (Nombre)

(20)

Sistema formal

Sistemas de tipos

Sistemas de tipos

• Ejemplo: (Env ∅) El contexto de tipificación vacío siempre es válido

(21)

Sistema formal

Sistemas de tipos

Sistemas de tipos

• Ejemplo (reglas de tipificación):

Γ ⊥ n::Int

(Val n)

(n=0, ±1, ±2...)

Γ ◊⊥ El tipo de un valor entero

es Int en cualquier contex-to de tipificación válido

(22)

Sistema formal

Sistemas de tipos

Sistemas de tipos

• Ejemplo (reglas de tipificación):

Γ ⊥ M+N::Int

(Val +)

Si las expresiones M y N son de tipo entero en Γ, también M+N lo es

(23)

Lenguajes tipificados

Tipos

Tipos

Un sistema de tipos es un conjunto de

(24)

Sistema formal

Sistemas de tipos

Sistemas de tipos

• Una derivación en un sistema de tipos es un árbol (invertido) de sentencias

• Cada una se obtiene de las inmediatamente superiores por aplicación de una regla

• Una sentencia válida es la que se puede obtener como raíz de una derivación

(25)

Sistema formal

Sistemas de tipos

Sistemas de tipos

• Ejemplo: ∅ ⊥ 1::Int ∅ ⊥ 2::Int ∅ ⊥ 1+2::Int

(por Env ∅) (por Env ∅)

∅ ◊⊥ ∅ ◊⊥

(por Val n) (por Val n)

(26)

Problemas de tipificación

Sistemas de tipos

Sistemas de tipos

• Dos problemas fundamentales sobre tipifica-ción de expresiones de programa:

– Comprobación de tipos (type checking): Dados

M, Γ y τ, comprobar si es válida

– Inferencia de tipos (type inference o type

deduction): Dada M, obtener, en su caso, Γ y τ de forma que sea válida

Γ ⊥ M :: τ

(27)

Problemas de tipificación

Sistemas de tipos

Sistemas de tipos

• En ambos casos, es esencial disponer de algoritmos para realizar dichas tareas:

– Algoritmo de comprobación de tipos (typechecking algorithm)

– Algoritmo de inferencia de tipos (type inference algorithm)

• La existencia y eficacia de éstos depende mucho del sistema de tipos

(28)

Problemas de tipificación

Sistemas de tipos

Sistemas de tipos

Haskell utiliza el sistema de tipos (polimórficos)

de Hindley-Milner que admite comprobación de tipos (Mycroft) e inferencia de tipos (Milner)

(29)

Sistemas de tipos

Sistemas de tipos

Problemas de tipificación

• El sistema de tipos de Hindley-Milner tiene sus limitaciones: la función

selfapplication f = f f

(30)

Sistemas de tipos

Sistemas de tipos

Problemas de tipificación

• Ejemplo: Dadas las ecuaciones

fun f lista1 lista1 = f lista1 + f lista2 imposible = fun length [1,2,3] “abc”

la expresión imposible no admite ningún tipo dentro de este sistema

(31)

Problemas de tipificación

Sistemas de tipos

Sistemas de tipos

La elección de un sistema de tipos

(32)

Sistemas de tipos

Sistemas de tipos

Problemas de tipificación

• Los algoritmos de comprobación de tipos (Mycroft) e inferencia de tipos (Milner) no son totalmente equivalentes

(33)

Sistemas de tipos

Sistemas de tipos

Problemas de tipificación

• Ejemplo: consideremos la ecuación g x = 1:g (g ‘c’)

El algoritmo de Milner falla al tratar de encontrar el tipo de g. Especificando

g :: a -> [Int]

el intérprete (que utiliza el algoritmo de Mycroft en ese caso) acepta la definición

(34)

Sistemas de tipos

Sistemas de tipos

Problemas de tipificación

• Ejemplo: consideremos la ecuación g x = g 1

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)

(35)

Problemas de tipificación

Sistemas de tipos

Sistemas de tipos

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

(36)

Polimorfismo paramétrico

Polimorfismo

Polimorfismo

• 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

(37)

• Ejemplo: la función length :: [a] -> Int

puede verse como una función con infinitos monotipos

[Int] -> Int, [Bool] -> Int,

[Int -> Int] -> Int, ...

Polimorfismo paramétrico

Polimorfismo

(38)

• 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 paramétrico

Polimorfismo

(39)

• 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 paramétrico

Polimorfismo

(40)

El sistema de tipos de Hindley-Milner

asegura que toda expresión tipificable tiene un tipo principal único

Polimorfismo paramétrico

Polimorfismo

(41)

• 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

Sobrecarga

Polimorfismo

(42)

• Este tipo de polimorfismo se denomina polimorfismo ad-hoc o sobrecarga

(overloading)

Sobrecarga

Polimorfismo

(43)

Sobrecarga

Polimorfismo

Polimorfismo

• Ejemplo: los operadores aritméticos (+), (-), (*), (/), ..., suelen estar sobrecargados:

(+) :: Int -> Int -> Int

(+) :: Float -> Float -> Float

(+) :: Complex -> Complex -> Complex corresponden a distintos usos de (+). Otro:

(44)

Sobrecarga

Polimorfismo

Polimorfismo

• 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

(45)

Sobrecarga

Polimorfismo

Polimorfismo

• 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?

(46)

Sobrecarga

Polimorfismo

Polimorfismo

• Matemáticamente: sean

f : D E y g : D E

dos funciones. Tenemos que

f =D → E g si y sólo sixD, f(x)=E f(x)

Si D es infinito, o f no es computable,

(47)

Sobrecarga

Polimorfismo

Polimorfismo

• 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:

(48)

Sobrecarga

Polimorfismo

Polimorfismo

En Haskell, el polimorfismo ad-hoc se

(49)

Sobrecarga

Polimorfismo

Polimorfismo

• Una clase es una colección de tipos

• Todos los tipos pertenecientes a una clase deben tener definidas ciertas operaciones

(50)

Sobrecarga

Polimorfismo

Polimorfismo

• 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 (<) y (<=) para comparar elementos entre sí

(51)

Sobrecarga

Polimorfismo

Polimorfismo

class Eq a where -- simplificado (==), (/=) :: a -> a -> Bool

class Eq a => Ord a where -- simplificado (<), (<=), (>), (>=) :: a -> a -> Bool

Ord es una

(52)

Sobrecarga

Polimorfismo

Polimorfismo

• 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

(53)

Sobrecarga

Polimorfismo

Polimorfismo

• 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

(54)

Sobrecarga

Polimorfismo

Polimorfismo

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

(55)

Sobrecarga

Polimorfismo

Polimorfismo

• 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

(56)

Sobrecarga

Polimorfismo

Polimorfismo

• Ejemplo: En realidad, bastaría con escribir data Nat = Cero | S Nat

(57)

Sobrecarga

Polimorfismo

Polimorfismo

• La clase Num se define como

class (Eq a, Show a) => Num a where (+),(-),(*) :: a -> a -> a

(58)

Sobrecarga

Polimorfismo

Polimorfismo

• Podemos añadir el tipo Nat a la clase Num: instance Num Nat where

Cero + n = n (S n) + m = S (n+m) Cero * n = Cero (S n) * m = m + (n*m) No es preciso definir todas las operaciones (¡¡pero no se podrán usar!!)

(59)

Sobrecarga

Polimorfismo

Polimorfismo

• Ahora podríamos escribir, directamente: fact Cero = S Cero

fact (S n) = (S n) * fact n

(60)

Desarrollo

Desarrollo

1. Tipos

2. Tipos básicos y tipos numéricos 3. Tipos algebraicos

4. Tipos funcionales: orden superior, definición de funciones

5. Listas y árboles

(61)

• Los tipos básicos proporcionados por Haskell son: – Booleanos – Caracteres – Tuplas – Cadenas – Tipos numéricos

Tipos básicos

Tipos básicos

(62)

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

(63)

Booleanos

• El perfil de la clase Enum es: class Enum a where

succ,pred :: a -> a toEnum :: Int -> a fromEnum :: a -> Int

Tipos básicos

Tipos básicos

¡¡Simplificado!!

(64)

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

(65)

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

(66)

Caracteres

Tipos básicos

Tipos básicos

• 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

(67)

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

(68)

Tipos básicos

Tipos básicos

• El tipo tupla pertenece a las clases Eq, Ord, Show y Enum, entre otras

• Operaciones usuales sobre tuplas:

– Proyección izq: fst :: (a,b) -> a – Proyección der: snd :: (a,b) -> b

¡¡Sólo con pares!!

(69)

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

(70)

Tipos básicos

Tipos básicos

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

(71)

Tipos numéricos

Tipos numéricos

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

Números en Haskell

Preludio Estándar Librerías

(72)

Tipos numéricos

Tipos numéricos

• 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

(73)

Tipos numéricos

Tipos numéricos

• 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

(74)

Tipos numéricos

Tipos numéricos

Números enteros

class (Eq a, Show a) => Num a where (+),(-),(*) :: a -> a -> a

negate :: a -> a abs,signum :: a -> a

(75)

Tipos numéricos

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

(76)

Tipos numéricos

Tipos numéricos

• 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

(77)

Tipos numéricos

Tipos numéricos

• 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

(78)

Tipos numéricos

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

(79)

Tipos numéricos

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

(80)

Tipos numéricos

Tipos numéricos

Números reales

class (Num a) => Fractional a where (/) :: a -> a -> a

recip :: a -> a

(81)

Tipos numéricos

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

(82)

Tipos numéricos

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

(83)

Tipos numéricos

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

(84)

Tipos numéricos

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

(85)

Tipos numéricos

Tipos numéricos

Números reales

Otras operaciones de interés son:

(^) :: (Integral b, Num a) => a -> b -> a

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

(86)

Tipos numéricos

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

(87)

Tipos numéricos

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

(88)

Tipos numéricos

Tipos numéricos

Num Int,Integer,Float,Double Real Int,Integer,Float,Double Fractional Float,Double Integral Int,Integer RealFrac Float,Double RealFloat Float,Double Floating Float,Double

(89)

Desarrollo

Desarrollo

1. Tipos

2. Tipos básicos y tipos numéricos

3. Tipos algebraicos

4. Tipos funcionales: orden superior, definición de funciones

5. Listas y árboles

(90)

Tipos algebraicos

Tipos

Tipos

• 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)

(91)

Tipos algebraicos

Tipos

Tipos

• 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)

(92)

Tipos algebraicos

Tipos

Tipos

• 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)

Simples

Estructurados

(93)

Tipos algebraicos

Tipos

Tipos

• 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)

(94)

Tipos algebraicos

Tipos

Tipos

• 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

(95)

Tipos algebraicos

Tipos

Tipos

• Ejemplo:

Int := 0 | 1 | 2 | 3 | ··· | -1 | -2 | -3 | ··· TreeInt := L Int | B TreeInt TreeInt Valores de este tipo son:

(96)

1

4

2 3

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

• Ejemplo de valor del tipo TreeInt

Tipos algebraicos

Tipos

(97)

Tipos algebraicos

Tipos

Tipos

• 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)

(98)

Desarrollo

Desarrollo

1. Tipos

2. Tipos básicos y tipos numéricos 3. Tipos algebraicos

4. Tipos funcionales: orden superior, definición de funciones

5. Listas y árboles

(99)

Tipos funcionales

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]

(100)

Valores funcionales

Tipos funcionales

Tipos funcionales

• Los valores funcionales pueden especificarse de dos formas:

– explícitamente: mediante expresiones lambda

(101)

Expresiones lambda

Definición de funciones

Definición de funciones

• 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

(102)

Expresiones lambda

Definición de funciones

Definición de funciones

• Ejemplo \ x y -> x+y \ x -> 2*x \ x -> True \ m n -> B (L m) (L n)

(103)

Expresiones lambda

Definición de funciones

Definición de funciones

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

(104)

Ecuaciones

Definición de funciones

Definición de funciones

• 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

(105)

Parámetros formales

Definición de funciones

Definición de funciones

• 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

(106)

Definición de funciones

Definición de funciones

• Ejemplos:

doble x = x+x triple x = 3*x

seisveces x = doble (triple x)

fact n = if n==0 then 1 else n*fact (n-1)

(107)

Definición de funciones

Definición de funciones

• Ejemplos: doble x = x + x triple x = 3 * x Funciones primitivas Parámetros formales

(108)

Definición de funciones

Definición de funciones

• Ejemplos:

doble x = x+x triple x = 3*x

seisveces x = doble (triple x)

Otras funciones de usuario

(109)

Definición de funciones

Definición de funciones

• Ejemplos:

doble x = x+x triple x = 3*x

seisveces x = doble (triple x)

fact n = if n==0 then 1 else n*fact (n-1)

Recursividad

(110)

Parámetros formales y guardas

Definición de funciones

Definición de funciones

• Una función f se describe mediante ecuaciones de la forma:

f x1 · · · xk | c = r

(111)

Parámetros formales y guardas

Definición de funciones

Definición de funciones

• Ejemplos: fact n | n==0 = 1 | n>0 = n*fact (n-1) sign x | x<0 = neg | x==0 = cero | x>0 = pos

(112)

Parámetros formales y guardas

Definición de funciones

Definición de funciones

• Ejemplos: Guardas fact n | n==0 = 1 | n>0 = n*fact (n-1) sign x | x<0 = neg | x==0 = cero | x>0 = pos

(113)

Ajuste de patrones

Definición de funciones

Definición de funciones

• 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

(114)

• 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)

Ajuste de patrones

Definición de funciones

(115)

• Ejemplos: Patrones Patrones Ajuste de patrones

Definición de funciones

Definición de funciones

length [] = 0 length (x:xs) = 1+length xs data Nat = Cero | S Nat

first Cero _ = []

(116)

Ajuste de patrones

Definición de funciones

Definición de funciones

• 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)

(117)

Ajuste de patrones

Definición de funciones

Definición de funciones

• Ejemplo: la expresión S (S Cero) se ajusta al patrón S x pero no al patrón Cero

S (S Cero)

S x Cero

S (S Cero)

X

(118)

Ajuste de patrones

Definición de funciones

Definición de funciones

El ajuste de patrones permite clasificar datos

(119)

Distinción de casos

Definición de funciones

Definición de funciones

• Una función f se describe mediante ecuaciones de la forma:

f p1 · · · pk = case x of

q1 -> e1 ...

qn -> en

• Donde

p

1

· · · p

k,

q

1

· · · q

n

son patrones, x

(120)

Distinción de casos

Definición de funciones

Definición de funciones

• Ejemplo: length xs = case xs of [ ] -> 0 (y:ys) -> 1+length ys

(121)

Cláusulas where

Definición de funciones

Definición de funciones

• Una función f se describe mediante ecuaciones de la forma:

f p1 · · · pk = e where l1 = r1

... ln = rn

• Donde

l

1

· · · l

n

son patrones o partes

izquierdas de definiciones de función, y

(122)

Definición de funciones

Definición de funciones

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

(123)

Orden superior

Orden superior

• En programación funcional, las funciones son ‘ciudadanos de primera clase’ (first

class citizens):

(124)

Orden superior

Orden superior

• En programación funcional, las funciones son ‘ciudadanos de primera clase’ (first

class citizens):

– Pueden ser pasadas, como argumentos, a otras funciones

(125)

• 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

Orden superior

(126)

• Ejemplos:

map f [] = []

map f (x:xs) = (f x):map f xs

map aplica una función f

a cada elemento de una lista

add x y = x+y add2 = add 2

add2 añade 2 al número

que se le pasa como argumento

aplicación parcial

Orden superior

Orden superior

(127)

Currificación

• A cada función (sobre k-tuplas)

f: D1 × D2 × ··· × DkE

le corresponde una función

fC: D1(D2( ···

(

DkE)···)

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

(128)

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

Orden superior

Orden superior

(129)

Currificación

• El operador -> es asociativo por la derecha

a -> b -> c equivale a

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

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

f a b equivale a (f a) b y difiere de f (a b)

Orden superior

(130)

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

f e

tiene sentido pleno: se trata de una función

f e :: b -> c

Orden superior

(131)

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 map (+ 2) [1,2]

Orden superior

Orden superior

(132)

Desarrollo

Desarrollo

1. Tipos

2. Tipos básicos y tipos numéricos 3. Tipos algebraicos

4. Tipos funcionales: orden superior, definición de funciones

5. Listas y árboles

(133)

Bibliografía

Bibliografía

[Car97] L. Cardelli. Type Systems.

[PE93] R. Plasmeijer and M. van Eekelen. Functional

Programming and Parallel Graph Rewriting. Addison-Wesley, Reading, MA, 1993

[Rea93] C. Reade. Elements of Functional Programming. Addison-Wesley, Reading, MA, 1993

(134)

Figure

Updating...

References

Related subjects :