2009-08-28 19 views
15

Questa domanda è stato ispirato da questo answer a un'altra domanda, che indica che è possibile rimuovere ogni occorrenza di un elemento da un elenco utilizzando una funzione definita come:Haskell: inferenza di tipo e la funzione di composizione

removeall = filter . (/=) 

Lavorando fuori con carta e matita dai tipi di filter, (/=) e (.), la funzione ha un tipo di

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

che è esattamente quello che ci si aspetta in base al suo contratto. Tuttavia, con GHCi 6.6, ottengo

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

a meno che non specificare il tipo in modo esplicito (nel qual caso funziona benissimo). Perché Haskell deduce un tipo così specifico per la funzione?

risposta

28

Perché Haskell deduce un tipo così specifico per la funzione?

GHCi utilizza type defaulting per dedurre un tipo più specifico da un insieme di possibili. È possibile evitare questo facilmente disabilitando the monomorphism restriction,

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

E 'anche interessante notare che, se non si assegna un nome all'espressione, coontrollore dei tipo sembra evitare inadempiente Tipo:

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