In Haskell ist der Functor-Typenklassen-Functor wie folgt definiert (siehe zB Haskell-Wiki ):
class Functor (f :: * -> *) where
fmap :: (a -> b) -> f a -> f b
Soweit ich (bitte korrigieren Sie mich , wenn ich falsch bin) zu verstehen, wie ein Funktor nur als Zielkategorie eine Kategorie eines Typkonstruktor aufgebaut haben kann, zB []
, Maybe
usw. Auf der anderen Seite kann man von functors denkt jede Kategorie mit als Ziel eines Funktors, zB die Kategorie aller Haskell-Typen. Dies Int
könnte beispielsweise ein Objekt in der Zielkategorie eines Funktors sein, nicht nur Maybe Int
oder [Int]
.
Was ist die Motivation für diese Einschränkung bei Haskell-Funktoren?
f
Recht herum ? Und in Ihrem Szenariof
sollte es genau wie eine normale Haskell-Funktion sein und Typen zu Typen zuordnen. In Haskell dürfen nur Typkonstruktoren verwendet* -> *
werden. Typfamilien sind allgemeiner, aber sie müssen immer vollständig angewendet werdenAntworten:
Es gibt überhaupt keine Einschränkung! Als ich anfing, die kategorietheoretischen Grundlagen für Typkonstruktoren zu lernen, verwirrte mich genau dieser Punkt ebenfalls. Wir werden darauf kommen. Aber lassen Sie mich zuerst ein wenig Verwirrung stiften. Diese zwei Anführungszeichen:
und
Zeigen Sie, dass Sie falsch verstehen, was ein Funktor ist (oder zumindest, dass Sie Terminologie falsch verwenden).
Functors nicht konstruieren Kategorien. Ein Funktor ist eine Zuordnung zwischen Kategorien. Funktoren bringen Objekte und Morphismen (Typen und Funktionen) in der Quellkategorie zu Objekten und Morphismen in der Zielkategorie.
Beachten Sie, dass dies bedeutet, dass ein Funktor tatsächlich ein Paar von Zuordnungen ist: eine Zuordnung zu Objekten F_obj und eine Zuordnung zu Morphismen F_morph . In Haskell ist der Objektteil F_obj des Funktors der Name des Typkonstruktors (z. B.
List
), während der Morphism-Teil die Funktion istfmap
(es ist Sache des Haskell-Compilers, die zu sortieren, auf diefmap
wir in einem gegebenen Ausdruck verweisen). Wir können also nicht sagen, dass diesList
ein Funktor ist; nur die kombination vonList
undfmap
ist ein funktor. Trotzdem missbrauchen die Leute die Notation; Programmierer rufenList
einen Funktor auf, während Kategorietheoretiker dasselbe Symbol verwenden, um auf beide Teile des Funktors zu verweisen.Darüber hinaus sind in der Programmierung fast alle Funktoren Endofunktionen , dh die Quell- und Zielkategorie sind identisch - die Kategorie aller Typen in unserer Sprache. Nennen wir diese Kategorie Typ . Ein Endofunctor F on Type ordnet einen Typ T einem anderen Typ FT und eine Funktion T -> S einer anderen Funktion FT -> FS zu . Dieses Mapping muss natürlich den functor-Gesetzen entsprechen.
Unter Verwendung
List
als Beispiel: Wir haben einen TypkonstruktorList : Type -> Type
, und eine Funktionfmap: (a -> b) -> (List a -> List b)
, die zusammen einen Funktor bilden. TEs gibt noch einen letzten Punkt, der geklärt werden muss. Schreiben
List int
nicht schaffen , eine neue Art von Listen von ganzen Zahlen. Dieser Typ existierte bereits . Es war ein Objekt in unserer Kategorie Typ .List Int
ist einfach ein Weg, sich darauf zu beziehen.Nun fragen Sie sich, warum ein Funktor keinen Typ, sagen wir abbilden kann,
Int
oderString
. Aber es kann! Man muss nur den Identity-Funktor benutzen. Für jede Kategorie C ordnet der Identitätsfunktor jedes Objekt sich selbst und den Morphismus sich selbst zu. Es ist unkompliziert zu überprüfen, ob diese Zuordnung den Funktionsgesetzen entspricht. In Haskell wäre dies ein Typkonstruktorid : * -> *
, der jeden Typ auf sich selbst abbildet. Wertet zum Beispielid int
zu ausint
.Darüber hinaus kann man sogar konstante Funktoren erstellen , die alle Typen einem einzigen Typ zuordnen. Zum Beispiel der Funktor
ToInt : * -> *
, in demToInt a = int
für alle Typena
und alle Morphismen der ganzzahligen Identitätsfunktion zugeordnet sind:fmap f = \x -> x
quelle
f a
, wobeif
es sich meines Wissens um einen Typkonstruktor handelt. Soweit ich mich aus der Kategorietheorie erinnere, muss dies eine Art kanonische Repräsentation sein (ursprüngliches Objekt in einer Kategorie von Kategorien? Vielleicht verwende ich die Terminologie falsch.) Wie auch immer, ich werde Ihre Antwort sorgfältig lesen. Danke vielmals.[]
und:
. Ich meinte das mit kanonischer Darstellung.(_, int)
, der einen Typa
zu dem Produkttyp(a, int)
und eine Funktionf : 'a -> 'b
zug : 'a * int -> 'a * int
nimmt, nicht induktiv.f : 'a -> 'b
aufg : 'a * int -> 'b * int
?