2009-08-28 16 views
15

Ta kwestia była inspirowana przez ten answer do innej kwestii, wskazując, że można usunąć wszystkie wystąpienia elementu z listy za pomocą funkcji zdefiniowano jako:Haskell: rodzaj wnioskowania i funkcja skład

removeall = filter . (/=) 

Praca it out z ołówka i papieru z rodzajów filter, (/=) i (.) funkcja ma typ

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

dokładnie to, czego można się spodziewać na podstawie jego zamówienia. Jednakże w przypadku GHCi 6.6 otrzymuję

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

, chyba że określę typ jawnie (w takim przypadku działa poprawnie). Dlaczego Haskell wnioskuje o takim specyficznym typie funkcji?

Odpowiedz

28

Dlaczego Haskell wnioskuje o takim konkretnym typie funkcji?

GHCi używa type defaulting, aby wywnioskować bardziej konkretny typ spośród zestawu możliwych. Można to łatwo uniknąć wyłączając the monomorphism restriction,

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

Warto również zauważyć, że jeśli nie przypisać nazwę do wypowiedzi, typechecker wydaje się uniknąć zalegających typu:

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