¿Qué es un tipo?
Bool
Bool
tiene dos valores True
(verdadero) y False
(falso).v :: T
representa que v
es un valor del tipo T
y se dice que v
tiene tipo T
''.:type
ghci> :type True
True :: Bool
ghci> :type False
False :: Bool
Bool -> Bool
está formado por todas las funciones cuyo argumento y valor son booleanos.Bool -> Bool
ghci> :type not
not :: Bool -> Bool
Inferencia de tipos
f :: A -> B, e :: A
-------------------
f e :: B
ghci> :type not True
not True :: Bool
ghci> :type not False
not False :: Bool
ghci> :type not (not False)
not (not False) :: Bool
ghci> :type not 3
Error: No instance for (Num Bool)
ghci> :type 1 + False
Error: No instance for (Num Bool)
Ventajas de los tipos
ghci> :type 1 `div` 0
1 `div` 0 :: (Integral t) => t
ghci> 1 `div` 0
*** Exception: divide by zero
Bool
(Valores lógicos):
True
y False
.Char
(Caracteres):
'a'
, 'B'
, '3'
, '+'
String
(Cadena de caracteres):
"abc"
, "1 + 2 = 3"
Int
(Enteros de precisión fija):
123
, -12
Integer
(Enteros de precisión arbitraria):
1267650600228229401496703205376
.Float
(Reales de precisión arbitraria):
1.2
, -23.45
, 45e-7
Double
(Reales de precisión doble):
1.2
, -23.45
, 45e-7
[T]
es el tipo de las listas de elementos de tipo T
.[False, True] :: [Bool]
['a','b','d'] :: [Char]
["uno","tres"] :: [String]
[]
, es la lista vacía.['a','b'] :: [Char]
['a','b','c'] :: [Char]
[['a','b'],['c']] :: [[Char]]
(T1, T2, ..., Tn)
es el tipo de las n-tuplas cuya componente i-ésima es de tipo Ti
.(False,True) :: (Bool,Bool)
(False,'a',True) :: (Bool,Char,Bool)
()
, es la tupla vacía.('a','b') :: (Char,Char)
('a','b','c') :: (Char,Char,Char)
(('a','b'),['c','d']) :: ((Char,Char),[Char])
Tipos de funciones
T1 -> T1
es el tipo de las funciones que aplica valores del tipo T1
en valores del tipo T2
.not :: Bool -> Bool
isDigit :: Char -> Bool
Funciones con múltiples argumentos o valores
suma (x,y)
es la suma de x
e y
. Por ejemplo, suma (2,3)
es 5
.suma :: (Int,Int) -> Int
suma (x,y) = x+y
deCeroA n
es la lista de los números desde 0
hasta n
. Por ejemplo, deCeroA 5
es [0,1,2,3,4,5]
.deCeroA :: Int -> [Int]
deCeroA n = [0..n]
Parcialización
suma' :: Int -> (Int -> Int)
suma' x y = x+y
suma'
toma un entero x
y devuelve la función suma' x
que toma un entero y
y devuelve la suma de x
e y
. Por ejemplo,ghci> :type suma' 2
suma' 2 :: Int -> Int
ghci> :type suma' 2 3
suma' 2 3 :: Int
mult :: Int -> (Int -> (Int -> Int))
mult x y z = x*y*z
mult
toma un entero x
y devuelve la función mult x
que toma un entero y
y devuelve la función mult x y
que toma un entero z
y devuelve x*y*z
. Por ejemplo,ghci> :type mult 2
mult 2 :: Int -> (Int -> Int)
ghci> :type mult 2 3
mult 2 3 :: Int -> Int
ghci> :type mult 2 3 7
mult 2 3 7 :: Int
Aplicación parcial
suma'
y mult
son currificadas.ghci> (suma' 2) 3
5
suc :: Int -> Int
suc = suma' 1
suc x
es el sucesor de x
. Por ejemplo, suc 2
es 3
.Convenios para reducir paréntesis
Int -> Int -> Int -> Int
representa a Int -> (Int -> (Int -> Int))
mult x y z
representa a ((mult x) y) z
length
es polimófica. Comprobación:ghci> :type length
length :: [a] -> Int
a
, length
toma una lista de elementos de tipo a
y devuelve un entero.a
es una variable de tipos.length
:length [1, 4, 7, 1] == 4
length ["Lunes", "Martes", "Jueves"] == 3
length [reverse, tail] == 2
Ejemplos de funciones polimórficas
fst :: (a, b) -> a
fst (1,'x') == 1
fst (True,"Hoy") == True
head :: [a] -> a
head [2,1,4] == 2
head ['b','c'] == 'b'
take :: Int -> [a] -> [a]
take 3 [3,5,7,9,4] == [3,5,7]
take 2 ['l','o','l','a'] == "lo"
take 2 "lola" == "lo"
zip :: [a] -> [b] -> [(a, b)]
zip [3,5] "lo" == [(3,'l'),(5,'o')]
id :: a -> a
id 3 == 3
id 'x' == 'x'
sum
está sobrecargada. Comprobación:ghci> :type sum
sum :: (Num a) => [a] -> a
a
, sum
toma una lista de elementos de tipo a
y devuelve un valor de tipo a
.Num a
es una restricción de clases.C a
, donde C
es el nombre de una clase y a
es una variable de tipo.sum [2, 3, 5] == 10
sum [2.1, 3.23, 5.345] == 10.675
Ejemplos de tipos sobrecargados
(-) :: (Num a) => a -> a -> a
(*) :: (Num a) => a -> a -> a
negate :: (Num a) => a -> a
abs :: (Num a) => a -> a
signum :: (Num a) => a -> a
5 :: (Num t) => t
5.2 :: (Fractional t) => t
Clase | Descripción |
---|---|
Eq |
tipos comparables por igualdad |
Ord |
tipos ordenados |
Show |
tipos mostrables |
Read |
tipos legibles |
Num |
tipos numéricos |
Integral |
tipos enteros |
Fractional |
tipos fraccionarios |
La clase Eq
(tipos comparables por igualdad)
Eq
contiene los tipos cuyos valores con comparables por igualdad.
Métodos:
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
Bool
, Char
, String
, Int
, Integer
, Float
y Double
.False == True == False
False /= True == True
'a' == 'b' == False
"aei" == "aei" == True
[2,3] == [2,3,2] == False
('a',5) == ('a',5) == True
La clase Ord
(tipos ordenados)
Ord
es la subclase de Eq
de tipos cuyos valores están ordenados.(<), (<=), (>), (>=) :: a -> a -> Bool
min, max :: a -> a -> a
Bool
, Char
, String
, Int
, Integer
, Float
y Double
.False < True == True
min 'a' 'b' == 'a'
"elegante" < "elefante" == False
[1,2,3] < [1,2] == False
('a',2) < ('a',1) == False
('a',2) < ('b',1) == True
La clase Show
(tipos mostrables)
Show
contiene los tipos cuyos valores se pueden convertir en cadenas de caracteres.
Método:
show :: a -> String
Bool
, Char
, String
, Int
, Integer
, Float
y Double
.show False == "False"
show 'a' == "'a'"
show 123 == "123"
show [1,2,3] == "[1,2,3]"
show ('a',True) == "('a',True)"
La clase Read
(tipos legibles)
Read
contiene los tipos cuyos valores se pueden obtener a partir de cadenas de caracteres.
Método:
read :: String -> a
Bool
, Char
, String
, Int
, Integer
, Float
y Double
.read "False" :: Bool == False
read "'a'" :: Char == 'a'
read "123" :: Int == 123
read "[1,2,3]" :: [Int] == [1,2,3]
read "('a',True)" :: (Char,Bool) == ('a',True)
La clase Num
(tipos numéricos)
Num
es la subclase de Eq
y Show
de tipos cuyos valores son números(+), (*), (-) :: a -> a -> a
negate, abs, signum :: a -> a
Int
, Integer
, Float
y Double
.2+3 == 5
2.3+4.2 == 6.5
negate 2.7 == -2.7
abs (-5) == 5
signum (-5) == -1
La clase Integral
(tipos enteros)
Integral
es la subclase de Num
cuyo tipos tienen valores enteros.div :: a -> a -> a
mod :: a -> a -> a
Int
e Integer
.11 `div` 4 == 2
11 `mod` 4 == 3
La clase Fractional
(tipos fraccionarios)
Fractional
es la subclase de Num
cuyo tipos tienen valores no son enteros.(/) :: a -> a -> a
recip :: a -> a
Instancias: Float
y Double
.
Ejemplos:
7.0 / 2.0 == 3.5
recip 0.2 == 5.0
A. Gibiansky Typeclasses: Polymorphism in Haskell.