Clases de Tipos

Anuncio
Tema V
Clases de Tipos
1
Noción de clase de tipos en Haskell
„
„
La noción de clase se utiliza para agrupar tipos, o
tuplas de tipos, con arreglo a la disponibilidad de
unas determinadas funciones, con el mismo nombre
y tipos equivalentes, aunque posiblemente con
métodos distintos para cada tipo de la clase.
Desde otro punto de vista, la noción de clase es el
concepto que utiliza Haskell para introducir
sobrecarga en funciones.
2
Definición de una clase de tipos
class <nombre> <par-tipo> {<par-tipo>}* where
<declaración de función>
{<declaración de función>}*
{<definición de función>}*
class Eq a where
(==) (/=) :: a->a->Bool
x /= y = not (x == y)
3
Funciones polimorfas
‰
‰
De cada función que aparece en una definición de clase se
dice que es polimorfa y de su nombre se dice que está
sobrecargado (el mismo nombre sirve para designar
funciones con distintos tipos concretos y distintos
métodos de cálculo).
Los métodos que aparecen en una definición de clase son
métodos por defecto, aplicables sólo a aquellos tipos de la
clase para los que no exista un método particular.
4
Declaración de instancia de una clase
‰ Para declarar un tipo como miembro de una clase se
utiliza una declaración de instancia donde se concretan
los métodos aplicables a cada una de las funciones
características de la clase.
instance <nom-clase> <tipo> {<tipo>}* where
<def-método>
{<def-método>}
‰ Si para alguna función no se da un método, se utiliza su
método por defecto que deberá aparecer en la
definición de la clase
5
Declaraciones de instancias (ejemplos)
instance Eq
True
False
_
Bool where
== True =
== False =
== _
=
True
True
False
instance Eq Char where
c==d = ord c == ord d
instance Eq Int where
(==) = primEqInt
6
Declaraciones de instancias (ejemplos)
data Nat = Cero | Suc Nat
instance Eq
Cero
Suc x
_
Nat where
== Cero = True
== Suc y = x==y
== _
= False
7
Contextos
‰ Con los nombres de clases se construyen predicados,
relativos a parámetros de tipos, de la forma:
<nom-clase> <par_tipo> {<par_tipo>}
que indican que el parámetro de tipo (o secuencia de
parámetros) debe ser una instancia de la clase citada
‰ Estos predicados (o conjunciones de ellos) se utilizan para
limitar el rango de variación de algunos parámetros de tipo en
las expresiones de tipo, constituyendo una declaración de
contexto, que debe preceder a la expresión afectada, en la
forma:
(<nom-clase> <par_tipo> {<par_tipo>}
{,<nom-clase> <par_tipo> {<par_tipo>}}*) => expresión
8
Uso de contextos (I)
Los contexto se utilizan:
‰ En las declaraciones de funciones genéricas para exigir que
determinados parámetros de tipo que dispongan de ciertas
operaciones
elemento_de :: (Eq a) => a -> [a] -> Bool
x `elemento_de` []
= False
x `elemento_de` (y:ys) = x==y||(x `elemento_de` ys)
contenida_en :: (Eq a) => [a] -> [a] -> Bool
[] `contenida_en` ys
= True
(x:xs)`contenida_en`ys = x`elemento_de`ys &&
xs`contenida_en`ys
9
Uso de contextos (II)
‰
En las declaraciones de instancia para tipos genéricos, p.e.:
instance (Eq a) =>
[]
== []
x:xs == y:ys
_ == _
Eq [a] where
= True
= x==y && xs==ys
= False
Donde el contexto indica que para que un tipo lista [a] sea
instancia de la clase Eq es necesario que lo sea el tipo a de
las componentes.
10
Uso de contextos (III)
instance (Eq a,Eq b) => Eq (a,b) where
(x,y)==(u,v) = x==u && y==v
data ArbolH a = H a | B (ArbolH a) (ArbolH a)
instance (Eq a) => Eq (Arbol a) where
H x == H y
= x==y
B x y == B u v = x==u && y==v
11
Uso de contextos (IV)
‰
En las definiciones de clases:
class (Eq a) => Ord a where
(<),(<=),(>=),(>) :: a -> a -> Bool
max, min
:: a -> a -> a
x<y = x<=y && x/=y
x>=y = y<=x
x>y = y<x
max x y | x>=y = x
| y>=x = y
min x y | x<=y = x
| y<=x = y
12
Subclases
‰
‰
‰
La aparición de un contexto en una definición de clase indica
que los tipos de dicha clase deben ser instancias de las
clases del contexto.
Esta circunstancia se suele indicar diciendo que la clase en
cuestión se define como subclase de las clases del contexto,
o también, que las clases del contexto son superclases de la
clase, y que ésta hereda las operaciones de las otras.
Sin embargo esta herencia es engañosa pues el mecanismo de
instanciación no convierte automáticamente las instancias de
una clase en instancias de sus superclases; sino que hay que
realizar todas las instanciaciones necesarias explícitamente.
13
Subclases (ejemplo)
data Mod2 = O | I
instance Ord Mod2 where
I<=O = False
_<=_ = True
instance Eq Mod2 where
O==O = True
I==I = True
_==_ = False
14
Clases de tipos predefinidas en
Hugs
15
Clase Eq
class Eq a where
(==), (/=) :: a -> a -> Bool
-- Minimal complete definition: (==) or (/=)
x == y
= not (x/=y)
x /= y
= not (x==y)
16
Clase Ord
class (Eq a) => Ord a where
compare
:: a -> a -> Ordering
(<), (<=), (>=), (>)
:: a -> a -> Bool
max, min
:: a -> a -> a
-- Minimal complete definition: (<=) or compare
-- using compare can be more efficient for complex types
compare x y | x==y
= EQ
| x<=y
= LT
| otherwise = GT
x
x
x
x
<=
<
>=
>
y
y
y
y
max x y
min x y
|
|
|
|
x >= y
otherwise
x <= y
otherwise
=
=
=
=
compare
compare
compare
compare
=
=
=
=
x
y
x
y
x
x
x
x
y
y
y
y
/=
==
/=
==
GT
LT
LT
GT
17
Clase Enum
class Enum a where
succ, pred
toEnum
fromEnum
enumFrom
enumFromThen
enumFromTo
enumFromThenTo
::
::
::
::
::
::
::
a -> a
Int -> a
a -> Int
a -> [a]
a -> a -> [a]
a -> a -> [a]
a -> a -> a -> [a]
-----
[n..]
[n,m..]
[n..m]
[n,n'..m]
-- Minimal complete definition: toEnum, fromEnum
succ
= toEnum . (1+)
. fromEnum
pred
= toEnum . subtract 1 . fromEnum
enumFrom x
= map toEnum [ fromEnum x .. ]
enumFromTo x y
= map toEnum [ fromEnum x .. fromEnum y ]
enumFromThen x y = map toEnum [ fromEnum x, fromEnum y ..]
enumFromThenTo x y z = map toEnum [ fromEnum x, fromEnum y
.. fromEnum z ]
18
Clase Show
type ShowS
= String -> String
class Show a where
show
:: a -> String
showsPrec :: Int -> a -> ShowS
showList :: [a] -> ShowS
-- Minimal complete definition: show or showsPrec
show x
= showsPrec 0 x ""
showsPrec _ x s = show x ++ s
showList []
= showString "[]"
showList (x:xs) = showChar '[' . shows x . showl xs
where showl []
= showChar ']'
showl (x:xs)= showChar ','.shows x.
showl xs
19
Clase Num
class (Eq a, Show a) => Num a where
(+), (-), (*) :: a -> a -> a
negate
:: a -> a
abs, signum
:: a -> a
fromInteger
:: Integer -> a
fromInt
:: Int -> a
-- Minimal complete definition: All,
-- except negate or (-)
x - y
= x + negate y
fromInt
= fromIntegral
negate x
= 0 – x
20
Ejercicios
‰
‰
Defínase un tipo Conjunto a, basado en la representación
de conjuntos mediante listas, junto con las operaciones
contenido, union, interseccion y diferencia, propias
de conjuntos, así como la igualdad de manera que se pueda
utilizar el operador ‘==‘.
Defínase un tipo de datos Racional, correspondiente a los
números racionales, utilizando una representación binómica
(numerador,denominador), junto con una función racNormal
que simplifique la representación de un número racional a su
forma irreducible, y las operaciones aritméticas de manera
que se puedan utilizar los operadores infijos habituales ‘+’,
‘-’, ‘*’ y ‘/’ .
21
Descargar