Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Pablo Nogueira School of Computer Science and IT Universidad de Nottingham, Reino Unido
Charla presentada en la Facultad de Inform atica de Madrid, 17 de Diciembre de 2004 Correcciones del 28 de Noviembre de 2005
Contenido de la charla
1. 2.
Qu e es la programac on gen erica y qu e t ecnicas hay por ah . Presentar las ideas en que se basa Generic Haskell.
Repaso de conceptos
Dos formas de abstracci on: De control: bucles, condicionales, funciones, rutinas, sincronizaci on, etc. - Separaci on entre interfaz e implementaci on De datos: tipos de datos abstractos, objetos, etc. - Separaci on entre interfaz e implementaci on Parametrismo: abstraer sobre ciertas entidades que pasan a ser par ametros, p.e., una expresi on se puede abstraer a una funci on considerando ciertas variables como par ametros. Encapsulaci on: ocultaci on de la informaci on de implementaci on.
Genericidad
Genericidad: Parametrismo + Instanciaci on + Encapsulaci on Las formas de genericidad se clasican seg un: 1. Qu e entidades son par ametros. - Generalmente se parametriza sobre valores y tipos de datos. nico programa trabaja con - Single Program Multiple Data: un u cualquier (o un conjunto) de tipos de datos. - Determinan el rango del Los mecanismos de instanciaci on y especializaci on des-generizaci on C omo se mantiene la encapsulaci on.
2. 3.
Programacin Genrica
Polimorsmo: un valor tiene muchos tipos. Variedades de polimorsmo: Subtipado (= herencia) Reusar mediante extensi on. Param etrico universal: ML, (im)predicativo, etc. Param etrico acotado: type classes, tipos calicados, etc. Ad-hoc: sobrecarga, poliaridad, multim etodos, etc. En el mundo funcional no se usan del todo debido a la tiran a de la inferencia. C++ Standard Template Library: b asicamente param etrico. Politipismo o polimorsmo estructural: PolyP , Generic Haskell, Scrap your Boilerplate. Tipos dependientes: una expresi on de tipos puede contener un valor, p.e., List a n es el tipo de listas de elementos de tipo a que tienen longitud n.
Haskell 98
Haskell es un lenguaje funcional Puro los efectos se realizan en m onadas. Perezoso sem antica no-estricta, memoizaci on. Polimorsmo universal y acotado Systema Fw + type classes. Fuertemente tipado = ausencia de errores de ejecuci on. Tipos de datos algebraicos con gesti on autom atica de memoria. En realidad Haskell es un lenguaje que se dene por su implementaci on y su implementaci on est andar es el Glasgow Haskell Compiler.
data List t = Nil | Cons t (List t) length :: List t Int length Nil = 0 length (Cons x xs) = 1 + length xs
Tipos de datos parametrizados: funciones a nivel de datos. Hay orden superior: se puede parametrizar sobre datos (payload) y funciones de datos (shape). Las mismas ideas a nivel de tipo: parametrismo universal, acotado, estructural, . . . , mecanismos de instanciaci on y especializaci on.
data TreeInt data Tree a data BTree a b data GTree f a data BList a -- Instanciaciones TreeInt
= Empty | Leaf Int| Node TreeInt TreeInt = Empty | Leaf a = Empty | Leaf a | Node (Tree a) (Tree a) | Node b (BTree a b) (BTree a b)
= GEmpty| GLeaf a | GNode (f (GTree f a)) = Nil | Cons a (BList (a,a)) -- irregular
Tree Int
type TreeChar = Tree Char type ArithExp = BTree Int (Int Int Int) type LGTree type BGTree = GTree List = GTree BList
Tipos y orden
El tipo de una funci on est a capturado por la siguiente gram atica: ::= |
Donde engloba los tipos base, p.e., Int o Char. El orden de la funci on se calcula como sigue: orden() = 0 orden(1 2 ) = m ax( 1 + orden(1 ), orden(2 ) )
Tipos y gneros
Al nivel de tipos, el g enero (kind) de una funci on de tipos captura el orden y la aridad. El g enero es el g enero de los tipos que no son funciones de tipo. ::= |
orden() orden(1 2 )
Una funci on de tipos t es de orden superior si orden(t) > 0. No exactamente el tipo de un tipo: type classes.
Int TreeInt Tree Tree Int BTree BTree Char GTree GTree List BGTree BList
: * : * : * * : * : * * * : * * : (* *) * * : * * : (* *) * * * : * *
Politipismo (I)
Las funciones y tipos polim orcos son param etricos sobre tipos de datos. La instanciaci on es una sustituci on, p.e.:
length :: a:*. List a Int
La funci on calcula la longitud de la lista independientemente del ametro impl cito valor de la variable de tipo a, que es un par (Systema F ). Las funciones y tipos polit picos tambi en son param etricos sobre otros tipos, pero la instanciaci on es m as compleja, basada en la estructura de la denici on del tipo de datos:
length t:* * :: a:*. t a Int
Politipismo (II)
gsize_List gsize_Set
length :: List a Int length [] = 0 length (x:xs) = 1 + length xs gsizeL :: a:*. (a Int) (List a Int) gsizeL gsa [] = gUnit [] gsizeL gsa (x:xs) = gsa x + gsizeL gsa xs length = gsizeL (const 1) gUnit = const 0 -- fijado !
sizeT :: BTree a b Int sizeT Empty = 0 sizeT (Leaf x) = 1 sizeT (Node x l r) = 1 + sizeT l + sizeT r
gsizeT :: a:*. (a Int) ( b:*. (b Int) (BTree a b Int)) gsizeT gsa gsb Empty gsizeT gsa gsb (Leaf x) = gUnit Empty = gsa x + gsizeT gsa gsb r sizeT = gsizeT (const 1) (const 1)
sizeG :: GTree f a Int sizeG GEmpty = 0 sizeG (GLeaf x) = 1 sizeG (GNode y) = ? gsizeG :: f:* *. ( a:*. (a Int) (f a Int)) ( a:*. (a Int) (GTree f a Int)) gsizeG gsf gsa GEmpty = gUnit GEmpty gsizeG gsf gsa (GLeaf x) = gsa x gsizeG gsf gsa (GNode y) = gsf (gsizeG gsf gsa) y
t:(* *) * *.
gsize :: t:* *. ( a:*. (a Int) (t a Int)) ( b:*. (b Int) (t t b Int))
Size es un tipo polig enero (polykinded) denido inductivamente en ametro. funci on del g enero del tipo t que toma como par
type Size * t = t Int t = a. Size k a Size l (t a) type Size k l
La notaci on Size k t indica que Size es param etrico en el g enero k y enero. toma un tipo t de dicho g Por ejemplo:
Size (* *) (* *) = t. Size * * = t. ( a. Size * ( a. Size * GTree t Size * * a Size * a Size * (GTree t) (t a)) ((GTree t) a))
La estructura de los datos sugiere la estructura de la soluci on, inclusive para tipos irregulares (recursi on no uniforme). Tipos b asicos y Unit tienen un tama no jo. Los par ametros del tipo llevan asociados funciones argumento que se pasan como argumento. La denici on de la funci on se determina a partir de la denici on de la estructura del tipo (sumas de productos).
La funci on gsize toma como argumento el tipo t y tiene como tipo Size k t, donde k es el g enero de t.
gsize t:k gsize Char gsize Int gsize Bool gsize Unit gsize a+b gsize a+b gsize ab :: Size k = const 0 = const 0 = const 0 = const 0 gsa gsb (Inl x) = gsa x gsa gsb (Inr y) = gsb y gsa gsb (x,y) = gsa x + gsb y t
gsize t:k gsize Char gsize Int gsize Bool gsize Unit gsize a+b gsize a+b gsize ab
x y x + gsize b y
Ejemplos de uso
aTree = Node A (Leaf 2) (Leaf 3) gsize BTree Int Char > 0 gsize BTree Int > 1 gsize BTree > 1 gsize BTree > 3 gsize List > 11 (const 1) "hello world" (const 1) (const 1) aTree (const 0) (const 1) aTree (const 1) aTree aTree
Implementacin
Una posible forma de programar la funci on polit pica es utilizar un valor que codique la estructura de sumas y productos del tipo. La instanciaci on de la funci on gen erica se realiza siguiendo la estructura del tipo argumento a partir de un patr on (template) que indica lo que hacer para cada suma, producto, o tipo b asico. As , por ejemplo, una llamada:
gsize List (const 1) [1,2,4]
Donde la denici on de gsizeL se ha obtenido a partir de un patr on y siguiendo la estructura de sumas de productos de List.
type Map *
t1 t2
= t1 t2 = a1 a2 t t
type Map k l
t1 t2
a1 a2. Map k
gmap t:k gmap Int gmap Unit gmap ab gmap a+b gmap a+b gmap List > "ABC" gmap BTree
Map l
:: Map k = = (x,y) id id
= (gmap a
x, gmap b x) y)
y)
(Inl x) = Inl (gmap a (Inr y) = Inr (gmap b chr [65, 66, 67]
type Map l k
Por ejemplo:
Map * * List = a. Map * a Map * (List a)
= a. (a a) (List a List a)
Soluci on: usar dos variables en la denici on del tipo polig enero (Map k t1 t2), y forzar a que el tipo de gsize sea para un mismo tipo:
gsize t:k :: Map k t t
Resumen
Una funci on polit pica es en realidad una familia de funciones; no s olo polim orcas sino tambi en sobrecargadas (overloaded) como la igualdad. Son catamorsmos: pretty-printers, igualdad, map, crush, codicaci on, tama no, etc. El tipo polig enero de la funci on es un patr on inductivo sobre el g enero del tipo de datos que la funci on toma como argumento. El cuerpo de la funci on es un patr on inductivo sobre la estructura (sumas de productos) de la denici on de dicho tipo argumento. Implementaci on: preprocesado, traducci on a funciones con polimorsmo de rango-n en Haskell.
Ms cosas
Type-indexed data types: tipos cuya denici on depende de la estructura de otro tipo. Dependency-style Generic Haskell. Extensi on de funciones (especializaci on). Seleccionar la codicaci on interna en forma de sumas de productos mediante vistas. Implementaci on por medio de type classes: Generics for the masses.
Anlisis: Ventajas
nica que computa sobre cualquier tipo Genericidad: una funci on u de datos denido en una cl ausula data. Podemos jugar con las funciones par ametro para obtener differentes c omputos.
Anlisis: Desventajas
La funci on es gen erica s olo en un tipo, no varios. No se puede programar un fold gen erico: el tipo de la funci on polit pica se determina a partir del g enero del tipo argumento, que no nos dice nada sobre su estructura.
type Fold * t = a:*. t ?? a
Necesitamos una funci on por cada constructor de valores. No se soportan tipos algebraicos restringidos, p.e.:
data Ord a Set a = MkSet [a]
Hay que saber c omo se realiza la instanciaci on para poder programar el patr on gen erico (p.e., sumas y productos se asocian a derechas). Grave: no se respeta la abstracci on de datos.