2009-08-28 37 views
15

Esta pregunta se inspiró en esta answer 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:Haskell: la inferencia de tipos y composición función

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 infiere un tipo tan específico para la función?

Respuesta

28

¿Por qué Haskell infiere un tipo tan específico para la función?

GHCi está usando type defaulting, para inferir un tipo más específico de un conjunto de posibles. Esto se puede evitar fácilmente mediante la desactivación de the monomorphism restriction,

Prelude> :set -XNoMonomorphismRestriction 
Prelude> let removeall = filter . (/=) 
Prelude> :t removeall 
removeall :: (Eq a) => a -> [a] -> [a] 
17

También vale la pena señalar que si no se asigna un nombre a la expresión, typechecker parece evitar Tipo de morosos:

Prelude> :t filter . (/=) 
filter . (/=) :: (Eq a) => a -> [a] -> [a] 
Cuestiones relacionadas