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
.Functor
will Arten von Art* -> *
,Barry
sieht aber nicht so aus, als hätte es diese Art. Was ist die Art vonBarry
? Nun, wir sehen, es werden drei Typparameter benötigt, also wird es so seinsomething -> something -> something -> *
. Man kann mit Sicherheit sagen, dass diesp
ein konkreter Typ ist und somit eine Art hat*
. Dennk
wir nehmen an*
und haben damit im weiteren Sinnet
eine Art* -> *
. Ersetzensomething
wir 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 t
von Art (* -> *) -> *
und k
Art sein (* -> *)
? Wenn dies der Fall wäre, was auch immer t
und k
tatsächlich t k
wä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.
k :: L
für jede Art habenL
, solanget :: L -> *
. Ein Compiler muss hier jedoch eine bestimmte auswählenL
oder auf ein Polykind zurückgreifen. Ein Polykind wäre die allgemeinste Option, aber hier wählt GHCL = *
(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).Antworten:
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
Barry
seinforall k. (k -> *) -> k -> * -> *
.quelle
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
,k
undp
ist vom Typ Variablen. Wie wir sehenyabba :: 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 sagenInt
oderChar
was auch immer ... Sie nennen es. Aber da es sich um einen Typ handelt, handelt es sich um eine Art Signatur*
.Der
t
Typ hier benötigt jedoch eine Typvariablek
, um einen Typ (dabba :: t k
) zuerstellen, sodass wir sicher sind, dass (hier keine Annahme).t
eine Art Signatur wie* -> *
undk
hat*
Sobald wir das wissen ... der Typ
Barry t k p
Art Signatur ,(* -> *) -> * -> * -> *
was bedeutet, dass est
dannk
und dann dauertp
und unsBarry
Typ gibt.Bearbeiten Lesen Sie unbedingt den Kommentar von @ luqui unten.
quelle
k
ist nicht darauf beschränkt, so zu sein,*
wie Sie es beim Ableiten behauptent
. Wir könntenk :: * -> *
undt :: (* -> *) -> *
zum Beispiel haben. Fügen Siedoo :: k Int
dem Datensatz ein Feld hinzu , und es wird ohne Probleme übergeben.