2009-08-28 22 views
15

Cette question a été inspirée par ce answer à une autre question, ce qui indique que vous pouvez supprimer toutes les occurrences d'un élément d'une liste à l'aide d'une fonction définie comme:Haskell: inférence de type et la composition fonction

removeall = filter . (/=) 

Travailler dehors avec un crayon et du papier à partir des types de filter, (/=) et (.), la fonction a un type de

removeall :: (Eq a) => a -> [a] -> [a] 

ce qui est exactement ce que vous attendez en fonction de son contrat. Cependant, avec GHCi 6.6, je reçois

gchi> :t removeall 
removeall :: Integer -> [Integer] -> [Integer] 

sauf si je spécifie le type explicitement (auquel cas cela fonctionne bien). Pourquoi Haskell infère-t-il un type spécifique pour la fonction?

Répondre

28

Pourquoi Haskell infère-t-il un type spécifique pour la fonction?

GHCi utilise type defaulting pour déduire un type plus spécifique d'un ensemble de possibles. Vous pouvez éviter cela facilement en désactivant the monomorphism restriction,

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

Il est également intéressant de noter que si vous ne donnez pas de nom à l'expression, typechecker semble éviter le défaut de type:

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