¿Cuándo se queja Haskell por escribir incorrectamente las funciones?
types typeclass (1)
Soy un novato de Haskell que intenta comprender cómo funciona la encuadernación de tipos en las funciones y cómo Haskell lo aplica.
Por ejemplo, aunque el tipo para la función
fst
es
fst :: (a, b) -> a
, el compilador no se queja de la función
fst''
.
Pero el compilador se queja de los enlaces de tipo para la función
elem''
.
fst'' :: (a,a) -> a
fst'' s = fst s
elem'' :: (Eq a, Eq b) => a -> [b] -> Bool
elem'' x xs = elem x xs
fst
tiene como tipo
fst :: (a, b) -> a
lo que significa que está bien definir una función:
fst'' :: (a, a) -> a
fst'' = fst
fst''
función
fst''
es
más restrictiva
que la función
fst
.
Independientemente de lo que reemplace
a
en su función
fst''
, está bien para
fst
.
Si, por ejemplo, se mantiene
a ~ Bool
, entonces llama a
fst
con la firma
fst :: (Bool, Bool) -> Bool
.
Pero dado que
fst
puede ocuparse de todos
a
y
b
, está bien que ambos elementos de la tupla sean
Bool
, por lo que dado que
fst
puede manejar tuplas para todos los tipos posibles para el primer y el segundo elemento de la 2-tupla, es definitivamente está bien si los dos elementos tienen el mismo tipo.
Este último no está bien, aquí define:
elem'' :: (Eq a, Eq b) => a -> [b] -> Bool
elem'' = elem
pero
elem
tiene el tipo
elem :: Eq a => a -> [a] -> Bool
.
Las firmas que puede hacer con la función
elem''
no son un subconjunto de las de la función
elem
, ya que puede establecer
a ~ Int
y
b ~ Bool
.
En ese caso, espera
elem :: Int -> [Bool] -> Bool
, pero evidentemente eso no se cumple, ya que los tipos
Int
y
Bool
son dos tipos diferentes, y en la firma
elem
, ambos son as.