Haskell Generic Type Parameters Resolver Tool oder Methode [duplizieren]
Schauen wir uns zum Beispiel die Typen dieser Funktionen an:
:t traverse
traverse
:: (Applicative f, Traversable t) => (a -> f b) -> t a -> f (t b)
:t id
id :: a -> a
Sie haben keine konkreten Typen, haben aber Parameter generischer Typ : a
, f
, b
, t
(korrigieren Sie mich , wenn sie nicht genannt generische Typparameter bitte)
Wenn ich auf diese Weise kombiniere id
und traverse
zusammen,
:t traverse id [Just 1, Just 2, Nothing]
traverse id [Just 1, Just 2, Nothing] :: Num b => Maybe [b]
Haskell können nun einige konkrete Typen für die Typvariablen binden a
, f
, b
, t
.
t = []
a = Maybe bb
f = Maybe
b = Num bb => bb
Im Folgenden schließe ich die Typen und Zuordnungen zu Parametern von Hand ab. Gibt es in Haskell eine Möglichkeit oder ein Werkzeug, dies automatisch zu tun, sodass einige zusammengesetzte Teile ( id
und traverse
) in einem Beispiel ihre Typensignaturen im Allgemeinen extrahieren und bei der Ausgabe erzeugt werden eine Zuordnung von generischen Typparameternamen zu konkreten abgeleiteten Typen?
Siehe auch das erste Beispiel hier: https://wiki.haskell.org/Type_inferencefür den Ausdruck " map ord
" darüber, wie Haskell Bindungen tatsächlicher Typen an Namen findet.
Wenn wir also an Funktionen suchen separat wir nur Namen haben a
, f
, b
, t
. Aber dann wir kombinieren die Funktionen und bieten einige zusätzliche Informationen wie [Just 1, Just 2, Nothing]
, und die Namen a
, f
, b
, t
sind konkrete Typen abgebildet.
Ich möchte diese Zuordnung automatisch abfangen und anzeigen.
Antworten
Ich denke , f
und t
sind generische Typkonstruktor Parameter , wie sie auf einer Art handeln Sie einen Typ (sie Art ist * -> *
, wo *
Mittel „ein konkreter Typ“).
traverse id
nicht Zusammensetzung ist, es Funktionsanwendung ist, wie Sie vorbei id
als Argument an traverse
. this . that
ist die Funktionszusammensetzung zwischen this
und that
im mathematischen Sinne, bei der Sie eine Funktion erstellen, die ihr (erstes) Argument als Eingabe für that
das Ergebnis dieser Anwendung angibt und an dieses weiterleitet this
.
Sie beziehen sich auf das Beispiel auf dieser Seite, wo dies angegeben ist
map :: (a -> b) -> [a] -> [b]
Char.ord :: (Char -> Int)
der Compiler in der Lage ist zu folgern , dass die Art der map ord
ist [Char] -> [Int]
, wie Sie selbst , indem er überprüfen kann :t map ord
auf der Kommandozeile.
Wenn Sie beim Tippen eine ähnliche Ausgabe mit konkreten Typen erwarten :t traverse id
, erhalten Sie diese aus dem einfachen Grund, der traverse id
immer noch eine polymorphe Funktion ist, nicht, sowohl in ihren konkreten Typargumenten als auch in ihren Typkonstruktorargumenten .
Nur ein etwas anderes Beispiel zu geben, wenn Sie eingeben :t traverse (:[])
, wo (:[])
Typen hat a -> [a]
, die ein spezieller Fall der ist , (Applicative f) => a -> f b
dass traverse
erwartet, können Sie diese Ausgabe erhalten,
traverse (:[]) :: Traversable t => t b -> [t b]
die, verglichen mit :t traverse
,
traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)
sagt Ihnen, dass traverse
in traverse (:[])
mit f === []
und "instanziiert" wurde a === b
.