Hinzufügen einer Anmerkung zu einem Typ Ausdruck wie in
e :: type
macht den Compiler Überprüfen, dass e
dass type
hat, sowie die Verwendung dass type
Typvariablen Instantiierung und Instanz-Auswahl zu fahren. Jedoch, wenn die type
polymorph ist, kann sie später noch instanziiert werden. Betrachten wir z.B.
(id :: a -> a) "hello"
Oben, a
wird String
trotz meiner Anmerkung instanziert werden. Des Weiteren wird
foo :: Int -> Int
foo = (id :: a -> a)
machen a
später zu Int
instanziiert werden. Die obige id
Annotation gibt keine Informationen an GHC: Sie weiß bereits, dass id
diesen Typ hat. Wir könnten es entfernen, ohne die Typprüfung überhaupt zu beeinflussen. Das heißt, die Ausdrücke id
und sind nicht nur dynamisch äquivalent, sondern auch statisch.
ähnlich sind die Ausdrücke
putStrLn . show
und
(putStrLn . show) :: Show x => x -> IO()
sind statisch gleichwertig: Wir Kommentierung nur den Code mit dem Typ GHC ableiten kann. Mit anderen Worten, wir stellen GHC keine Informationen zur Verfügung, die es nicht bereits kennt.
Nachdem die Annotation typisiert ist, kann GHC die Instanz x
weiter instanziieren. Die Monomorphie-Einschränkung macht das in Ihrem Beispiel. Um das zu verhindern, eine Anmerkung für die Bindung verwenden Sie einführen, nicht für den Ausdruck:
myprint :: Show x => x -> IO()
myprint = (putStrLn . show)
wilde Vermutung: die gefürchtete Monomorphie Einschränkung. – Jubobs
@Jubobs Das wäre meine Vermutung - außer dass eine explizite Art Signatur das nicht deaktiviert? – MathematicalOrchid
Verwenden Sie eine alte Version von GHC? Ich bin auf 7.8.3 und erhalte die Typensignatur, die man * allgemein * erwarten würde ('Zeige a => a -> IO()'), auch ohne einen Signaturausdruck zu verwenden. Getting '() -> IO()' scheint ein echtes Problem mit GHC. – MasterMastic