Haskell: Tipo de inferencia y la composición de funciones
-
20-09-2019 - |
Pregunta
Esta pregunta se inspiró en esta respuesta a otra pregunta, lo que indica que se puede quitar todas las apariciones de un elemento de una lista utilizando una función definida como:
removeall = filter . (/=)
Trabajando hacia fuera con lápiz y papel a partir de los tipos de filter
, (/=)
y (.)
, la función tiene un tipo de
removeall :: (Eq a) => a -> [a] -> [a]
que es exactamente lo que cabría esperar en función de su contrato. Sin embargo, con GHCi 6.6, consigo
gchi> :t removeall
removeall :: Integer -> [Integer] -> [Integer]
si no especifico el tipo de forma explícita (en cuyo caso se trabaja muy bien). ¿Por qué Haskell inferir un tipo tan específico para la función?
Solución
¿Por qué se Haskell inferir un tipo tan específico para la función?
GHCi está utilizando morosos , para inferir un tipo más específico de un conjunto de posibles. Esto se puede evitar fácilmente mediante la desactivación la restricción monomorphism ,
Prelude> :set -XNoMonomorphismRestriction
Prelude> let removeall = filter . (/=)
Prelude> :t removeall
removeall :: (Eq a) => a -> [a] -> [a]
Otros consejos
También vale la pena señalar que si no se asigna un nombre a la expresión, typechecker parece evitar el impago tipo:
Prelude> :t filter . (/=)
filter . (/=) :: (Eq a) => a -> [a] -> [a]