La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

1 Tipos inductivos y Pattern Matching Introducción a tipos inductivos y pattern matching Abstracciones con pattern matching. Traducción a cálculo lambda.

Presentaciones similares


Presentación del tema: "1 Tipos inductivos y Pattern Matching Introducción a tipos inductivos y pattern matching Abstracciones con pattern matching. Traducción a cálculo lambda."— Transcripción de la presentación:

1

2 1 Tipos inductivos y Pattern Matching Introducción a tipos inductivos y pattern matching Abstracciones con pattern matching. Traducción a cálculo lambda enriquecido Semántica de abtracciones con pattern matching Expresiones case

3 2 Un poco de historia La descripción de Iswim [Landin 66] hacía uso de inglés enriquecido con una sintaxis especial para denotar tipos inductivos. Burstall introdujo una notación más formal para definir esta clase de tipos en NPL [Burstall 77]. Iswim consideraba una forma simple de definición de funciones usando pattern matching. Fue usado con éxito para describir pruebas por inducción estructural por Burstall [Burstall 69] y para transformación de programas [Burstall and Darlington 77]. Fue incorporado luego a, por ejemplo, los lenguajes Hope, KRC, ML, Miranda, Orwel y Haskell.

4 3 Definición de tipos inductivos data Tree a = Leaf a | Branch (Tree a) (Tree a) Un objeto de tipo Tree a es o una Leaf, la que contiene un objeto de tipo a o una Branch que contiene dos objetos de tipo Tree a. El número de argumentos asociados a un constructor se conoce usualmente como la aridad del constructor en cuestión. Constructores pueden aparecer en la parte izquierda de una función: reflect Leaf a) = Leaf a reflect (Branch t1 t2) = Branch (reflect t2) (reflect t1) Se dice de una definición con esta forma que hace uso de pattern matching para efectuar análisis de casos.

5 4 Definición de tipos inductivos (2) Constructores en Haskell (y en Samba) son perezosos: sus componentes son evaluados sólo cuando (y si) son extraídos y usados, no cuando el objeto es construído. Casos particulares: data List a = Nil | Cons a (List a) data Pair a b = MkPair a b data Color = Blue | Green | Red Notación Traducción [] Nil (x:xs) Cons x xs [a] (List a) (x,y) MkPair x y (a,b) Pair a b

6 5 Una formulación general de tipos inductivos T = c 1 T 11... T 1r1 | c 2 T 21... T 2r2 donde T ij es un tipo... c i constructor de aridad r i | c n T n1... T nrn Esta formulación de T se puede entender de la siguiente forma : T = T 1 + T 2 +... + T n donde T i = T i1 x T i2 x... X T iri Entonces, T es una suma de productos

7 6 Pattern matching Aquí intentaremos ilustrar algunos de los aspectos más importantes de p.m., los que deberían ser contemplados en una implementación. reflect (Leaf a) = Leaf a reflect (Branch t1 t2) = Branch (reflect t2) (reflect t1) Leaf y Branch (en la parte izquierda de la definición) son llamados patterns. Cuando reflect es aplicado a un argumento, éste es primero evaluado para ver si machea a Leaf o a Branch (type checking asegura esto). Por ejemplo, si reflect es aplicado a una expresión que evalúa a ( Branch e1 e2 ), entonces la segunda ecuación es seleccionada con t1 ligado a e1 y t2 ligado a e2.

8 7 Pattern Matching (2) Orden, superposición y patterns constantes factorial 0 = 1 factorial n = n * factorial (n-1) Si las ecuaciones hubiesen sido escritas en el otro orden la primera siempre machearía. Patterns anidados y ecuaciones no exhaustivas lastElt (x:[]) = x lastElt (x:xs) = lastElt xs Pattern matching sobre varios argumentos xor False y = y xor True False = True xor True True = False

9 8 Pattern matching (3) Ecuaciones con guardas funnyLastElt (x:[]) = x funnyLastElt (x:xs) | x < 0 = x funnyLastElt (x:xs) | otherwise = funnyLastElt xs Cuando un pattern machea el argumento, las guardas son consideradas, en forma top-down. Si ninguna de las guardas se hace verdadera el pattern matching continúa con la siguiente ecuación. Variables repetidas en patterns noDups [] = [] noDups [x] = [x] noDups (x:x:xs) = noDups (x:xs) noDups (x:y:xs) = x : noDups (y:ys)

10 9 Resumen de problemas a ser considerados Patterns superpuestos Patterns constantes Patterns anidados Argumentos múltiples Conjunto de ecuaciones no exhaustivas Ecuaciones guardadas Variables repetidas

11 10 Definición de pattern Un pattern p es una variable v o una constante k (número, carácter, boolean, etc.) o un pattern de constructor de la forma (c p 1 p 2... p r ), donde c es un constructor de aridad r y p 1, p 2... p r son a su vez patterns. Todas las variables en un pattern deben ser distintas Un pattern de la forma (s p 1... p r ), donde s es un constructor de suma es llamado un pattern de suma. Un pattern de la forma (t p 1... p r ), donde t es un constructor de producto es llamado un pattern de producto.

12 11 Abstracciones lambda con pattern matching TD [ f v1... vn = e ] f = \v1... vn e] Análogamente : TD [ f p1... pn = e ] f = \TE[p1]... TE[pn] e] Ejemplo : fst (x,y) = x TD [fst (x,y) = x ] fst = \(Pair x y) x Cómo podemos traducir una definición de función en Samba a una abstracción con pattern matching? Cuál es el significado de una expresión de la forma \ p e?

13 12 Ecuaciones múltiples y falla Consideremos la definición de la siguiente función: f p 1 = e 1 f p 2 = e 2... f p n = e n Intuitivamente: pruebe la primer ecuación, si esta falla trate la segunda, etc. Esto introduce la idea de que un pattern-match puede fallar, lo que no necesariamente implica un error. Introducimos entonces dos valores distinguidos: FAIL y ERROR. f = \x -> ( ((\p 1 -> e 1 ) x) ((\p 2 -> e 2 ) x) donde x FV(e i )... TE[e i ] = e i ((\p n -> e n ) x) TE[p i ] = p i ERROR )

14 13 Ecuaciones múltiples y falla (2) El comportamiento de la función (infija) es descripto por las siguientes ecuaciones semánticas: a b = a si a y a FAIL FAIL b = b b Ejemplo reflect (Leaf a) = Leaf a reflect (Branch t1 t2) = Branch (reflect t2) (reflect t1) reflect = \ t -> ( (( \ (Leaf a) Leaf a) t) (( \ (Branch t1 t2) Branch (reflect t2) (reflect t1))) ERROR ) TD [ hd (x:xs) = x ] ? hd = \xs -> (((\ (Cons x xs) -> x) xs ) E RROR)

15 14 Argumentos múltiples Funciones con múltiples argumentos pueden fácilmente manipularse: TD [ f p 1 p 2... p n = e] f = \ v 1... v n (((\ p 1... p n e) v 1... v n ERROR) Debemos ahora especificar que pasa cuando ocurre una falla. Supongamos que f es aplicada a n argumentos y el primer pattern- match falla: (((\ p 1... p n e) e 1 e 2... e n FAIL e 2... e n Entonces sería deseable que toda la expresión falle. Agregamos la siguiente regla de reducción para FAIL: FAIL E FAIL

16 15 Argumentos múltiples (2) Ahora podemos continuar la reducción: FAIL e 2 e 3... e n FAIL e 3... e n FAIL La traducción es fácilmente extendida al caso en que f es definida mediante varias ecuaciones. Ejemplo: xor False y = y xor True False = True xor True True = False xor = \ x y -> ( (( \ False y -> y) x y) ( ( \ True False -> True ) x y) ( ( \ True True -> False ) x y) E RROR )

17 16 Semántica de abstracciones con pattern matching Ahora daremos una semántica (informal) para expresiones de la forma \ p -> e. Para eso definiremos reglas de evaluación (la función Eval ) para cada una de las formas de patterns: variables constantes constructores de suma constructores de producto

18 17 Semántica de patterns variable y constantes Variables Si el pattern p es una variable v entonces su significado es exactamente el mismo de la expresión \ v -> e. Constantes Para describir la semántica de patterns constantes debemos definir el valor de la expresión Eval [ \ k -> e] Eval [\ k -> e] a = Eval [e] si a = Eval [k] Eval [\ k -> e] a = FAIL si a Eval [k] y a Eval [\ k -> e] \ 1 -> + 3 4) 1 \ 1 -> + 3 4) 2 FAIL

19 18 Semántica de constructores de suma Ahora consideraremos el caso de patterns de constructores de la forma (s p1... pn): Eval [ \ (s p1... pn) -> e] (s a1... an) = Eval [\ p1... pn -> e] a1... an Eval [ \ (s p1... pn) -> e] (s a1... an) = FAIL (s s Eval [ \ (s p1... pn) -> e] = Operacionalmente las reglas se pueden entender de la siguiente forma: Para aplicar (\ (s p1... pn) -> e) a una expresión A primero evaluamos A para poder observar que tipo de valor es. Si esta evaluación no termina tampoco lo hace la aplicación (regla 3). Si evalúa a un objeto construído con un constructor distinto de s entonces la aplicación falla (regla 2). Si no, la primer regla se aplica.

20 19 Semántica para patterns de constructores de producto Consideremos las siguientes funciones: zeroAny x = 0 Eval [ zeroAny ] zeroList [] = 0 Eval [ zeroList] zeroPair (x,y) = 0 Eval [ zeroPair] Eval [zeroPair] ( lazy product matching) Eval [zeroPair] ( strict product matching) Eval [ \ (t p1... pn) -> e ] a = Eval [ \ p1... pn -> e ] (SEL-t-1 a)... (SEL-t-1 a) donde SEL-t-i (t a1... ai... an) = ai SEL-t-i

21 20 Semántica para patterns de constructores de producto (2) Veamos como la definición anterior de Eval funciona sobre zeroPair : zeroPair = \ (Pair x y) -> 0 Entonces Eval [zeroPair] = Eval [\ (Pair x y) -> 0] = Eval [\ x y -> 0] (SEL-Pair-1 (SEL-Pair-2 = Eval [\ y -> 0] (SEL-Pair-2 0

22 21 Expresiones case Las transformaciones anteriores producen programas muy ineficientes. La principal razón es que pattern-matches son efectuados en secuencia testeando cada vez por FAIL para cada ecuación que conforma la definición de una función. En general, sin embargo, un simple test alcanza para seleccionar la ecuación apropiada. Expresiones case proveen una notación para describir una forma simple de pattern-matching. La definición de reflect puede ser reescrita en función de case como sigue: reflect = \t -> case t of Leaf a => Leaf a Branch t1 t2 => Branch (reflect t2) (reflect t1)

23 22 Expresiones case (2) La forma general de una expresión case es case v of donde v es una variable (de tipo T), c1 v11... v1r1 => e1 e1...en son expresiones... vij son variables distintas cn vn1... vnrn => en c1... cn familia completa de constructores del tipo T Formalmente, esta construcción es equivalente a : (( \ (c1 v11... v1r1) -> e1) v) (( \ (cn vn1... vnrn) -> en) v) Intuitivamente expresiones-case corresponden a un multiway jump mientras que la expresión que usa corresponde a un if... then... elseif...

24 23 Compilación eficiente de pattern matching A partir de ahora nos concentraremos en como compilar definiciones de funciones que usan pattern matching a expresiones case, las que pueden ser eficientemente evaluadas. El siguiente ejemplo ilustra pattern matching en más de un pattern: mappairs f [] ys = [] mappairs f (x:xs)[] = [] mappairs f (x:xs)(y:ys) = f x y : mappairs f xs ys mappairs = \f xs ys -> case xs of Nil => Nil Cons x xs => case ys of Nil => Nil Cons y ys => Cons (f x y)(mappairs f xs ys)


Descargar ppt "1 Tipos inductivos y Pattern Matching Introducción a tipos inductivos y pattern matching Abstracciones con pattern matching. Traducción a cálculo lambda."

Presentaciones similares


Anuncios Google