Betrachten Sie den folgenden Code
%Vor% Die Musterübereinstimmung in useDynFoo
sollte die Verwendung von obsFoo
auf den Typ Foo f -> Foo Int
beschränken, was dazu führen sollte, dass nach einer Instanz von DynFoo Int
gesucht wird. Es sucht jedoch stattdessen nach einer Instanz von DynFoo t
für unbekanntes t
und schlägt natürlich fehl.
Wenn ich jedoch die Definition von useDynFoo
auf
Dann funktioniert es plötzlich, obwohl meine Typ-Signatur komplett redundant ist.
Also, warum passiert das und wie kann ich obsFoo
verwenden, ohne eine Typ-Signatur geben zu müssen?
Es ist klarer, wenn Sie es mit einem expliziten case
schreiben (Ansichtsmuster verdecken den WRT-Typ-Informationsfluss):
Hier ist die Information f ~ Int
perfekt zugänglich für 1
. Nun, aber dafür brauchen wir diese Information nicht: wir brauchen sie schon bei obsFoo foof
. Und die Information kann nicht dorthin gelangen: GADT-Musterübereinstimmungen wirken als eine vollständige "Typinformationsdiode", d. H. Jegliche Information von außen kann innerhalb des übereinstimmenden Bereichs verwendet werden, aber keine Information von innen kann ohne verwendet werden. (Aus guten Gründen natürlich, weil diese Information nur zur Laufzeit bestätigt werden kann, wenn Sie tatsächlich einen GADT-Konstruktor haben, von dem Sie nehmen können.)
Die interessantere Frage ist, warum funktioniert es, wenn Sie die :: Foo Int
Signatur hinzufügen? Nun, das ist insbesondere eine Verrücktheit des Betrachtungsmusters. Sehen Sie, das folgende würde nicht funktionieren:
Diese Information ist, wie Sie selbst sagten, völlig überflüssig.
Es stellt sich jedoch heraus, dass dieses Ansichtsmuster tatsächlich der Unterschrift auf den anderen Teil des Falls entspricht:
%Vor%und das ist ein ganz anderes Paar Schuhe, denn jetzt ist% code% nicht innerhalb der GADT-Musterübereinstimmung.
Ich weiß nicht, warum man Muster mit Unterschriften so sieht, vielleicht um dieses Muster möglich zu machen.
Typensignaturen sind bei Verwendung von GADTs nicht redundant. Beachten Sie den letzten Aufzählungspunkt von GHC-Benutzerhandbuch: GADTs
Tags und Links haskell type-inference typeclass gadt