Tipos inductivos y Pattern Matching Introduccin a tipos

  • Slides: 23
Download presentation
Tipos inductivos y Pattern Matching • Introducción a tipos inductivos y pattern matching •

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 1

Un poco de historia • La descripción de Iswim [Landin 66] hacía uso de

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. 2

Definición de tipos inductivos data Tree a = Leaf a | Branch (Tree a)

Definición de tipos inductivos data Tree a = Leaf a | Branch (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 t 1 t 2) = Branch (reflect t 2) (reflect t 1) Se dice de una definición con esta forma que hace uso de pattern matching para efectuar análisis de casos. 3

Definición de tipos inductivos (2) Constructores en Haskell (y en Samba) son perezosos: sus

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) Pair a b = Mk. Pair a b Color = Blue | Green | Red Notación [] (x: xs) [a] (x, y) (a, b) Traducción Nil Cons x xs (List a) Mk. Pair x y Pair a b 4

Una formulación general de tipos inductivos T = c 1 T 11. . .

Una formulación general de tipos inductivos T = c 1 T 11. . . T 1 r 1 | c 2 T 21. . . T 2 r 2. . . | cn Tn 1. . . Tnrn donde Tij es un tipo ci constructor de aridad ri Esta formulación de T se puede entender de la siguiente forma: T = T 1 + T 2 +. . . + Tn donde Ti = Ti 1 x Ti 2 x. . . X Tiri Entonces, T es una suma de productos 5

Pattern matching Aquí intentaremos ilustrar algunos de los aspectos más importantes de p. m.

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 (Branch t 1 t 2) = Branch (reflect t 2) (reflect t 1) y Branch (en la parte izquierda de la definición) son llamados patterns. Leaf 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 e 1 e 2), entonces la segunda ecuación es seleccionada con t 1 ligado a e 1 y t 2 ligado a e 2. 6

Pattern Matching (2) Orden, superposición y patterns constantes factorial 0 factorial n = =

Pattern Matching (2) Orden, superposición y patterns constantes factorial 0 factorial n = = 1 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 last. Elt (x: []) (x: xs) = x = last. Elt xs Pattern matching sobre varios argumentos xor False y = y xor True False = True xor True = False 7

Pattern matching (3) Ecuaciones con guardas funny. Last. Elt (x: []) = x (x:

Pattern matching (3) Ecuaciones con guardas funny. Last. Elt (x: []) = x (x: xs) | x < 0 = x (x: xs) | otherwise = funny. Last. Elt 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 no. Dups [] = [] no. Dups [x] = [x] no. Dups (x: x: xs) = no. Dups (x: y: xs) = no. Dups (x: xs) x : no. Dups (y: ys) 8

Resumen de problemas a ser considerados • Patterns superpuestos • Patterns constantes • Patterns

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

Definición de pattern Un pattern p es • una variable v • o una

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. . . pr), donde c es un constructor de aridad r y p 1, p 2. . . pr son a su vez patterns. Todas las variables en un pattern deben ser distintas Un pattern de la forma (s p 1. . . pr) , donde s es un constructor de suma es llamado un pattern de suma. Un pattern de la forma (t p 1. . . pr) , donde t es un constructor de producto es llamado un pattern de producto. 10

Abstracciones lambda con pattern matching TD [ f v 1. . . vn =

Abstracciones lambda con pattern matching TD [ f v 1. . . vn = e ] f = v 1. . . vn -> TE [e] Análogamente: TD [ f p 1. . . pn = e ] f = TE[p 1]. . . TE[pn] -> TE [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? 11

Ecuaciones múltiples y falla Consideremos la definición de la siguiente función: f p 1

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 pn = en 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). . . � ((pn’ -> en’) x) � ERROR ) donde x FV(ei) TE[ei] = ei’ TE[pi] = pi’ 12

Ecuaciones múltiples y falla (2) El comportamiento de la función (infija) � es descripto

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

Argumentos múltiples Funciones con múltiples argumentos pueden fácilmente manipularse: TD [ f p 1

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

Argumentos múltiples (2) Ahora podemos continuar la reducción: FAIL e 2 e 3. .

Argumentos múltiples (2) Ahora podemos continuar la reducción: FAIL e 2 e 3. . . en 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 = False xor = x y -> ( (( False y -> y) x y) � (( True False -> True ) x y) � (( True -> False ) x y) � ERROR ) 15

Semántica de abstracciones con pattern matching Ahora daremos una semántica (informal) para expresiones de

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 16

Semántica de patterns variable y constantes Variables Si el pattern p es una variable

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] a = Eval [e] Eval [ k -> e] a = FAIL Eval [ k -> e] = ( 1 -> + 3 4) 1 + 3 4 si a = Eval [k] si a Eval [k] y a ( 1 -> + 3 4) 2 FAIL 17

Semántica de constructores de suma Ahora consideraremos el caso de patterns de constructores de

Semántica de constructores de suma Ahora consideraremos el caso de patterns de constructores de la forma (s p 1. . . pn): Eval [ (s p 1. . . pn) -> e] (s a 1. . . an) = Eval [ p 1. . . pn -> e] a 1. . . an Eval [ (s p 1. . . pn) -> e] (s’ a 1. . . an) = FAIL (s s’) Eval [ (s p 1. . . pn) -> e] = Operacionalmente las reglas se pueden entender de la siguiente forma: Para aplicar ( (s p 1. . . 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. 18

Semántica para patterns de constructores de producto Consideremos las siguientes funciones: zero. Any x

Semántica para patterns de constructores de producto Consideremos las siguientes funciones: zero. Any x = 0 zero. List [] = 0 zero. Pair (x, y) = 0 Eval [ zero. Any ] = 0 Eval [ zero. List] = Eval [ zero. Pair] ? Eval [zero. Pair] = 0 (lazy product matching) Eval [zero. Pair] = (strict product matching) Eval [ (t p 1. . . pn) -> e ] a = Eval [ p 1. . . pn -> e ] (SEL-t-1 a). . . (SEL-t-1 a) donde SEL-t-i (t a 1. . . ai. . . an) = ai SEL-t-i = 19

Semántica para patterns de constructores de producto (2) Veamos como la definición anterior de

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

Expresiones case Las transformaciones anteriores producen programas muy ineficientes. La principal razón es que

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 t 1 t 2 => Branch (reflect t 2) (reflect t 1) 21

Expresiones case (2) La forma general de una expresión case es case v of

Expresiones case (2) La forma general de una expresión case es case v of c 1 v 11. . . v 1 r 1 => e 1. . . cn vn 1. . . vnrn => en donde v es una variable (de tipo T), e 1. . . en son expresiones vij son variables distintas c 1. . . cn familia completa de constructores del tipo T Formalmente, esta construcción es equivalente a: (( (c 1 v 11. . . v 1 r 1) -> e 1) v) �. . . � (( (cn vn 1. . . vnrn) -> en) v) Intuitivamente expresiones-case corresponden a un “multiway jump” mientras que la expresión que usa � corresponde a un “if. . . then. . . elseif. . . ” 22

Compilación eficiente de pattern matching A partir de ahora nos concentraremos en como compilar

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 = [] f (x: xs)[] = [] 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) 23