Aggiunta annotazione di tipo a un espressione come in
e :: type
rende il controllo compilatore che ha e
che type
, così come l'uso che type
per guidare variabili di tipo istanziazione e selezione esempio. Tuttavia, se lo type
è polimorfico, può essere istanziato in seguito. Si consideri ad es.
(id :: a -> a) "hello"
Sopra, a
vengono istanziati a String
, nonostante la mia annotazione. Inoltre,
foo :: Int -> Int
foo = (id :: a -> a)
farà a
creare un'istanza di Int
in seguito. L'annotazione sopra id
non fornisce alcuna informazione a GHC: sa già che id
ha quel tipo. Potremmo rimuoverlo senza modificare il tipo di controllo. Cioè, le espressioni id
e id :: a->a
non sono solo equivalenti dinamicamente, ma anche staticamente tali.
Allo stesso modo, le espressioni
putStrLn . show
e
(putStrLn . show) :: Show x => x -> IO()
sono staticamente equivalenti: stiamo solo annotare il codice con il tipo di GHC può dedurre. In altre parole, non forniamo alcuna informazione a GHC che non conosce già.
Dopo aver controllato l'annotazione, GHC può quindi istanziare ulteriormente x
. La restrizione del monomorfismo lo fa nel tuo esempio. Per evitare questo, utilizzare un'annotazione per il vincolante si stanno introducendo, non per l'espressione :
myprint :: Show x => x -> IO()
myprint = (putStrLn . show)
selvaggio indovinare: il temuto restrizione monomorfismo. – Jubobs
@Jubobs Anche questa sarebbe la mia ipotesi - tranne che una firma di tipo esplicito non lo disabilita? – MathematicalOrchid
Stai usando una vecchia versione di GHC? Sono su 7.8.3 e ottengo la segnatura del tipo che dovresti * generalmente * aspettare ('Mostra a => a -> IO()'), anche senza usare un'espressione di firma. Ottenere '() -> IO()' sembra un vero problema con GHC. – MasterMastic