Was ist die Annahme in "Learn You a Haskell", wenn die Art abgeleitet wird?

18

Diese Frage ist nicht subjektiv. In dem Buch, auf das verwiesen wird, wird ein sehr spezifisches Verb verwendet, und ich würde gerne verstehen, was die Implikation dieser Formulierung bedeutet, weil ich befürchte, etwas falsch zu verstehen.

Aus Learn You a Haskell ist der folgende Absatz der dritte und letzte, der "wir nehmen an *" enthält.

data Barry t k p = Barry { yabba :: p, dabba :: t k }  

Und jetzt wollen wir es zu einer Instanz machen Functor. Functorwill Arten von Art * -> *, Barrysieht aber nicht so aus, als hätte es diese Art. Was ist die Art von Barry? Nun, wir sehen, es werden drei Typparameter benötigt, also wird es so sein something -> something -> something -> *. Man kann mit Sicherheit sagen, dass dies pein konkreter Typ ist und somit eine Art hat *. Denn kwir nehmen an *und haben damit im weiteren Sinne teine Art* -> * . Ersetzen somethingwir nun einfach diese Arten durch die s, die wir als Platzhalter verwendet haben, und wir sehen, dass es eine Art von hat (* -> *) -> * -> * -> *.

Warum nehmen wir überhaupt etwas an? Beim Lesen von "Wir nehmen X an (dh wir nehmen an, dass X wahr ist)" ist es für mich selbstverständlich zu denken, dass wir auch den Fall berücksichtigen sollten, dass X falsch ist. Konnte im konkreten Fall des Beispiels nicht tvon Art (* -> *) -> *und kArt sein (* -> *)? Wenn dies der Fall wäre, was auch immer tund ktatsächlich t kwäre , wäre es immer noch ein konkreter Typ, nein?

Ich sehe, dass die gesamte Argumentation dann mit dem Compiler verglichen wird, aber ich glaube nicht, dass der Compiler davon ausgeht . Wenn ja, würde ich gerne wissen, was, wenn nicht, dann fürchte ich, dass mir die Bedeutung des Absatzes fehlt.

Enrico Maria De Angelis
quelle
4
Du hast Recht. In der Tat können wir k :: Lfür jede Art haben L, solange t :: L -> *. Ein Compiler muss hier jedoch eine bestimmte auswählen Loder auf ein Polykind zurückgreifen. Ein Polykind wäre die allgemeinste Option, aber hier wählt GHC L = *(Basic Haskell hat keine Polykinds, sie müssen als Erweiterung aktiviert werden). Da LYAH etwas wählt, das eher willkürlich ist, verwendet es das Wort "annehmen" (AFAICT).
Chi
1
Ok, vielleicht hat der Compiler angenommen , dass mich das zumindest weniger verwirrt hätte, als wir annehmen , oder überhaupt nicht.
Enrico Maria De Angelis

Antworten:

19

Tatsächlich geht der Compiler davon aus! Mit der PolyKinds-Erweiterung können Sie jedoch darum bitten. Sie können hier ausführlicher darüber lesen . Wenn diese Erweiterung aktiviert ist, wird die Art von Barrysein forall k. (k -> *) -> k -> * -> *.

Daniel Wagner
quelle
-1

Guter Punkt. Der Autor macht eine unnötige Annahme. Vielleicht nur, um das Verständnis in seinem Type Foo-Kapitel zu erleichtern, aber Leute wie Sie können dies zu Recht in Frage stellen.

Beide t, kund pist vom Typ Variablen. Wie wir sehen yabba :: p, kann es alleine leben, also ist es wie eine konstante Funktion, als ob es ein Wert anstelle eines Typs wäre, würde die Typensignatur sagen Intoder Charwas auch immer ... Sie nennen es. Aber da es sich um einen Typ handelt, handelt es sich um eine Art Signatur *.

Der tTyp hier benötigt jedoch eine Typvariable k, um einen Typ ( dabba :: t k) zu erstellen, sodass wir sicher sind, dass (hier keine Annahme) teine Art Signatur wie * -> *und khat* .

Sobald wir das wissen ... der Typ Barry t k p Art Signatur , (* -> *) -> * -> * -> *was bedeutet, dass es tdann kund dann dauert pund uns BarryTyp gibt.

Bearbeiten Lesen Sie unbedingt den Kommentar von @ luqui unten.

Reduzieren
quelle
7
kist nicht darauf beschränkt, so zu sein, *wie Sie es beim Ableiten behaupten t. Wir könnten k :: * -> *und t :: (* -> *) -> *zum Beispiel haben. Fügen Sie doo :: k Intdem Datensatz ein Feld hinzu , und es wird ohne Probleme übergeben.
Luqui
@luqui .. Ja, Sie haben Recht ... Ich werde diese Antwort nicht löschen, da Ihr Kommentar es wirklich wert ist, erwähnt zu werden.
Reduzieren Sie den