% Práctico Haskell 7: Clase de Tipos Monoid
y Functor
, Instancias Solapadas
Semigroup
y Monoid
En el teórico hemos hablado del que un tipo como Int
puede
tener ser instancia de las clases Semigroup
y Monoid
de dos maneras distintas.
Descargá y resolvé SemigroupMonoidInt.hs.
Instancias solapadas
Descargá y resolvé Solapamiento.hs
Al principio del módulo se encuentra la línea
{-# LANGUAGE FlexibleInstances #-}
.
Esta línea habilita la extensión FlexibleInstances
, que permite
que la cabeza de una declaración de instancia mencione tipos
anidados arbitrarios, como el siguiente:
instance C (Maybe Int)
IO
, Monoid
y Functor
Este ejercicio consiste en definir funciones de tipo IO algo
en una sola línea solo usando funciones de las clases Monoid
y Functor
.
Descargar y resolver MonFunIO.hs.
Tipos Algebraicos de Datos – Tipos Polimórficos
Definir los tipos y funciones siguientes en un módulo Haskell.
1. Minimo y clase Bounded
Considera la funcion minimo
que calcula cual es el menor valor
de una lista de tipo [a]
(con a
perteneciendo a la clase Ord
).
a) Definí minimo1
que funciona solo para el caso de las listas no vacías.
b) Definí minimo2
que funciona para todos los casos, limitando el tipo a
a la clase Bounded
para poder definir el caso base.
Para probar esa funcion dentro de ghci
con listas vacıas,
indicar el tipo concreto con tipos de la clase Bounded
,
por ejemplo: ([1,5,10]::[Int])
, ([]::[Bool])
, etc.
2. Tipos recursivos y polimórficos
Consideremos la siguiente definición de tipo de datos:
data ListAssoc a b = Empty
| Node a b (ListAssoc a b)
deriving Show
Los parámetross del constructor de tipo (ListAssoc
) indican que es un tipo polimórfico,
donde las variables a
y b
se pueden instanciar con distintos tipos;
por ejemplo:
type Diccionario = ListAssoc String String
type DNI = Int
type Padron = ListAssoc DNI String
Definí las siguientes funciones:
a) comodin :: Int -> ListAssoc Int Int
que, dada un entero positivo n
,
construye un lista asociativa de n
entradas desde n
hasta 1
, cada
entrada teniendo asociado el valor 0. Por ejemplo:
~~~haskell
comodin 1 == Node 1 0 Empty
comodin 3 == Node 3 0 (Node 2 0 (Node 1 0 Empty))
comodin 0 == Empty
~~~
b) existe :: Eq a => ListAssoc a b -> a -> Bool
que dada una lista y una
clave devuelve `True` si la clave está y `False` en caso contrario. c) `agregar :: Eq a => a -> b -> ListAssoc a b -> ListAssoc a b` que dada
una clave `a`, un dato `b` lo agrega en la lista si la clave `a` no existe.
En caso de que la clave `a` exista, se aplasta el dato anterior. d) Hacé que el tipo `ListAssoc` pertenezca a la clase `Monoid`, de tal forma
que cuando se combinan dos `ListAssoc` con `<>` , y existen claves duplicadas, se descarte
el dato correspondiente de la `ListAssoc` de la izquierda y quede el de la derecha.