Los constructores deben tener su
primera letra en mayúscula
Como se ve en ejemplo la parte
Izquierda antes del igual es el tipo de
dato, y la parte derecha son los valores
que puede tomar el tipo de dato
Palabra clave de Haskell para definir un nuevo tipo de dato
Para mostrar por consola
se agrega al final de la
declaración :deriving
(Show)
Record
syntax
Podemos almacenar información de una persona, datos
personales como como características de ella
ejemplo: data Person = Person String String Int Float String String
deriving (Show) , tenemos 6 tipos de datos lo que indica que
creamos un apersona con 6 datos: nombre , apellido, edad,
estatura y un un dato de información personal
ghci> let guy = Person "Javier" "Cardenas" 30 1.70 "2022669" "FResa"
ghci> guy Person "Javier" "Cardenas" 30 1.7 "2022669" "FResa"
Después de crear una persona, podemos crear funciones
que obtengan información por separado de la clase
persona que creamos anteriormente
data Persona = Persona String String Int Float String String deriving (Show)
primerNombre :: Persona -> String
primerNombre Persona primerNombre _ _ _ _
_) =primerNombre
let persona = Persona "Carlos" "Gomez" 30 1.70 "2022668" "Cl. l1 # 20-25"
*Main> primerNombre persona "Carlos"
*Main> apellido persona "Gomez"
Método para de definir tipos de dato
data Persona = Persona { primerNombre :: String ,
apellido :: String , edad :: Int , estatura :: Float ,
telefono :: String , direccion :: String } deriving
(Show)
Type parameters
Un constructor de datos puede tomar
algunos valores como parámetros y
producir un nuevo valor, un
constructor de tipos puede tomar
tipos como parámetros y producir
nuevos tipos
data Maybe a = Nothing | Just a
La (a) es un parámetro de tipo. Debido
a que hay un parámetro de tipo
involucrado en esta definición,
llamamos a Maybe un constructor de
tipos.
Just puede tomar cualquier
valor que le pasen que le
pase Maybe
Derived instances
Clase de tipos es una especie de
interfaz que define un
comportamiento, Un tipo puede ser
una instancia de esa clase si soporta
ese comportamiento
El tipo Int es una
instancia de la
clase Eq
La utilidad real está en las
funciones que actúan como
interfaz de Eq, que son == y /=
La clase de tipos Eq define el
comportamiento de cosas que
se pueden equiparar
Haskell puede derivar el comportamiento de nuestros tipos en las siguientes clases: Eq, Ord, Enum,
Bounded, Show y Read, si usamos la palabra clave deriving cuando los definimos, usando la palabra
clave deriving cuando los definimos
Al derivar una instancia de Eq para un tipo y luego se compara dos
valores de ese tipo usando == o /=, Haskell comprobará si los
constructores de tipo coinciden y luego comprobará si todos los
campos de ese constructor coinciden utilizando el operador = para
cada par de campos. Solo tenemos que tener en cuenta una cosa,
todos los campos del tipo deben ser también miembros de la clase
de tipos Eq.
Las clases de tipos Show y Read son para cosas que
pueden ser convertidas a o desde cadenas,
respectivamente. si un constructor de tipos tiene
campos, su tipo debe ser miembro de la clase Show o
Read si queremos que también forme parte de estas
clases.
Show sirve para convertir nuestro tipo a una cadena, Read sirve para convertir una
cadena a nuestro tipo su función es inversa. Aunque recuerda que cuando uses la
función read hay que utilizar una anotación de tipo explícita para decirle a Haskell
que tipo queremos como resultado. Si no ponemos el tipo que queremos como
resultado explícitamente, Haskell no sabrá que tipo queremos.
Podemos derivar instancias para la clase de tipo Ord, que es para tipos
que tienen valores que se pueden pedir. Si comparamos dos valores del
mismo tipo que se realizaron utilizando diferentes constructores, el valor
que se definió primero es considerados más pequeños. Por ejemplo,
considere el tipo Bool, que puede tener un valor de Falso o Verdadero.
Con el propósito de ver cómo se comporta cuando comparado, ejem: data
Bool = False | True deriving (Ord)
Type synonyms
Un sinónimo de tipo es un nuevo nombre para un tipo existente,
Los valores de diferentes sinónimos del mismo tipo son totalmente
compatibles. En Haskell puedes definir un sinónimo de tipo
utilizando type: type MyChar = Char, type String = [Char]
Los sinónimos de tipo también pueden ser parametrizados. Si
queremos un tipo que represente las listas de asociación pero
también queremos que sea lo suficientemente general como para
utilizar cualquier tipo de clave y valor, Ejem: type AssocList k v =
[(k,v)]
Una función que tomara un valor por clave en una lista de asociación
puede tener el tipo (Eq k) => k -> AssocList k v -> Maybe v. AssocList
es un constructor de tipos que toma dos tipos y produce un tipo
concreto, ejem: AssocList Int String
Recursive data structures
En haskell se pueden crear estructuras de datos
recursivas, en el que un valor de un cierto tipo
contenga valores de ese mismo tipo, el cual
seguirá conteniendo valores del mismo tipo y
así sucesivamente.
ejemplo: data List a = Empty | Cons a (List a) deriving (Show, Read, Eq, Ord)
Puede ser una lista vacía o una
combinación de un elemento y otra
lista.
sintaxis de registro: data List a = Empty | Cons { listHead :: a, listTail :: List a} deriving (Show, Read, Eq, Ord)
Typeclasses 102
clase de tipos Eq es para cosas que pueden ser equiparadas. Define las
funciones == y /=. Si tenemos un tipo (digamos, Car) y el comparar dos
coches con la función == tiene sentido, entonces tiene sentido que Car
sea una instancia de Eq.
definición de la clase
class Eq a where (==) :: a -> a -> Bool
(/=) :: a -> a -> Bool x == y = not (x /= y)
x /= y = not (x == y)
class Eq a where: significa que estamos
definiendo una clase de tipos nueva y
que se va a llamar Eq
La a es la variable de tipo y significa
que a representará el tipo que dentro
de poco hagamos instancia de Eq
No es obligatorio implementar los cuerpos de las
funciones, solo debemos especificar las declaraciones
de tipo de las funciones.
No necesariamente tiene que ser
una a puede ser cualquier letra o
palabra en minúscula
data TrafficLight = Red | Yellow | Green
instance Eq TrafficLight where Red == Red =
True Green == Green = True Yellow == Yellow =
True _ == _ = False
se utiliza: class, para definir nuevas
clases de tipos e instance, para hacer
que nuestros tipos tengan una
instancia para cierta clase de tipos.
Cuando se define class Eq a where, a
representa el tipo que hiciéramos
instancia después. cuando se
instancia, escribrimos instance Eq
TrafficLight where, remplazando la a
por el tipo actual.
class Eq a where (==)
:: a -> a -> Bool (/=) ::
a -> a -> Bool
A yes-no typeclass
La clase de tipos YesNo define una función
Esta función toma un valor de
un tipo cualquiera que puede
expresar algún valor de
verdad y nos dice si es
verdadero o no
class YesNo a where
yesno :: a -> Bool
instancia
instance YesNo Int where
yesno 0 = False yesno _ =
True