Zusammenfassung der Ressource
Creando nuestros propios tipos y clases de tipos
- Algebraic data
types intro
- data
- Ejemplo: data Bool = False | True
- 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
- apellido :: Persona -> String apellido
(Persona _ apellido _ _ _ _) =apellido
- 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
- La listas
vacias son
falsos
- instance YesNo [a] where
yesno [] = False yesno _ =
True
- listas no vacías
son verdaderas
- The Functor typeclass
- Se usa para cosas que
se pueden mapear
- implementación
- class Functor f where
fmap :: (a -> b) -> f a -> f b
- Toma una función de un
tipo a otro y una lista de
un tipo y devuelve una
lista del otro tipo
- instance Functor [] where
fmap = map
- hacer map o fmap sobre listas
vacías se obtiene un alista
vacía
- Kinds and some
type-foo
- Kinds pueden ser un tipo de un tipo
- ghci> :k Int
Int :: *
- * : significa que es de un tipo de dato concreto
- Concreto: que no toma parámetros o valores
- ghci> :k Maybe
Maybe :: * -> *
- toma tipo concreto com o Int
y devuelve un tipo Maybe Int
- ghci> :k Either
Either :: * -> * -> *
- Either toma dos tipos
concretos como
parámetros de tipo y
produce un tipo concret