Introducción a ML (2a. parte)

Anuncio
Laboratorio de Lenguajes de Programación
Introducción al lenguaje ML
2a. parte
Pedro A. Góngora Luna1
1.
Tipos de datos algebraicos
1.1.
Tipos enumerados
Además de los tipos básicos, tuplas y listas, en ML podemos crear nuestros propios tipos de datos.
El forma más simple son los tipos enumerados. Por ejemplo:
datatype planeta = Mercurio | Venus | Tierra | Marte |
Jupiter | Saturno | Urano | Neptuno;
En seguida podemos usar el nuevo tipo y los valores definidos:
- val p = Tierra;
val p = Tierra : planeta
- p;
val it = Tierra : planeta
- Tierra;
val it = Tierra : planeta
- val p = Marte;
val p = Marte : planeta
También, ML sobrecarga automáticamente el operador = para nuestro nuevo tipo:
- Mercurio = Jupiter;
val it = false : bool
- Marte = p;
val it = true : bool
Podemos usar funciones sobre nuestro tipo usando pattern matching:
1 [email protected]
1
- fun posicion
| posicion
| posicion
| posicion
| posicion
| posicion
| posicion
| posicion
val posicion =
Mercurio = 1
Venus
= 2
Tierra
= 3
Marte
= 4
Jupiter = 5
Saturno = 6
Urano
= 7
Neptuno = 8;
fn : planeta -> int
- posicion Tierra;
val it = 3 : int
También podemos usar _ en las clausulas como comodı́n:
- fun habitable Tierra = true
| habitable _
= false;
val habitable = fn : planeta -> bool
- habitable Tierra;
val it = true : bool
- habitable Venus;
val it = false : bool
A los valores Mercurio, Venus, etc., les llamamos constructores. En estos ejemplos, tenemos constructores de aridad 0, pero también podemos tener constructores n-arios. Por ejemplo:
- datatype pareja = P of bool * bool;
datatype pareja = P of bool * bool
- P(true,false);
val it = P (true,false) : pareja
Y podemos definir funciones sobre este nuevo tipo:
- fun p_or (P (false,false)) = false
| p_or _
= true;
val p_or = fn : pareja -> bool
- p_or (P (false,true));
val it = true : bool
- p_or (P (false,false));
val it = false : bool
1.2.
Tipos recursivos
Usando datatype, podemos crear estructuras de datos recursivas. Por ejemplo, un árbol binario
de enteros (con información en las hojas):
2
datatype tree = Hoja of int | Nodo of tree*tree;
De esta forma, el árbol:
1
o ◦ OOOO
OOO
ooo
o
o
OOO
oo
o
OOO
o
o
O
ooo
◦>
◦>
>>
>>
>>
>>
>>
>>
2
3
4
se representa como:
- val x = Nodo ( (Nodo (Hoja 1, Hoja 2)), (Nodo (Hoja 3, Hoja 4)) );
val x = Nodo (Nodo (Hoja #,Hoja #),Nodo (Hoja #,Hoja #)) : tree
Y podemos definir funciones recursivas sobre los tipos recursivos:
- fun cuentaHojas (Hoja _)
= 1
| cuentaHojas (Nodo (n1, n2)) = (cuentaHojas n1) + (cuentaHojas n2);
val cuentaHojas = fn : tree -> int
- cuentaHojas x;
val it = 4 : int
2.
Ejercicios
1. Defina una función sumaHojas que calcule la suma de los valores de todas las hojas de un árbol
binario.
2. Defina una función profundidad que calcule la profundidad de un árbol binario.
3. Podemos usar tipos recursivos para representar elementos sintácticos de un lenguaje. Considera
el lenguaje sencillo de las expresiones aritméticas:
AExp ::= n | a + a | a − a | a ∗ a
Esta pequeña gramática la podemos escribir en ML ası́:
datatype aexp = Lit of int | Sum of (aexp*aexp) |
Sub of (aexp*aexp) | Mul of (aexp*aexp);
Escribe una función eval que dada una expresión la evalúe y devuelva el resultado. Por ejemplo:
- eval (Lit 5);
val it = 5 : int
- eval (Sum (Lit 3, Lit 5));
val it = 8 : int
3
Descargar