Gibt es ein Konzept für so etwas wie koapplikative Funktoren, die zwischen Komonaden und Funktoren sitzen?


17

Jede Monade ist auch ein anwendbarer Funktor und jeder anwendbare Funktor ist ein Funktor. Auch jeder Komonade ist ein Funktor. Gibt es ein ähnliches Konzept zwischen Komonaden und Funktoren, so etwas wie ein koapplikativer Funktor, und welche Eigenschaften hat er?

FunctorsFunctorsAnwendbare Funktoren???MonadenComonaden

Update: Ich würde mich auch für mögliche Verwendungen eines solchen Konzepts interessieren.


Bist du sicher, dass du nicht nach Comonaden gesucht hast -> ??? -> Mitwirkende?
Josiah

1
@josiah Nein, soweit ich weiß, sind Comonaden Funktoren , keine Cofunktoren.
Petr Pudlák

1
Ist das fehlende Teil nicht teilbar ?
Gus

Antworten:


15

Vor allem:

Jede Monade ist auch ein anwendbarer Funktor und jeder anwendbare Funktor ist ein Funktor.

Dies gilt im Zusammenhang mit Haskell, aber ( Applicativeals "starker laxer monoidaler Funktor" zu lesen ) im Allgemeinen nicht, aus dem eher trivialen Grund, dass Sie "anwendbare" Funktoren zwischen verschiedenen monoidalen Kategorien haben können, während Monaden (und Comonaden) Endofunktoren sind .

Darüber hinaus ist die Identifizierung Applicativemit stark laxen monoiden Funktoren leicht irreführend, da zur Rechtfertigung des Namens (und der Typensignatur von (<*>)) ein Funktor zwischen geschlossenen monoiden Kategorien erforderlich ist, der sowohl die monoide Struktur als auch die interne Hom bewahrt . Dies könnte plausibel als "laxer geschlossener monoidaler Funktor" bezeichnet werden, mit der Ausnahme, dass ein Funktor zwischen monoidalen geschlossenen Kategorien, der eine Eigenschaft beibehält, die andere auf offensichtliche Weise erhält . Da Applicativein Hask nur Endofunktoren beschrieben werden , deren monoidale Struktur erhalten bleibt, erhalten (,)ihre Instanzen automatisch viele Eigenschaften, einschließlich ihrer Stärke , die auf diese Weise beseitigt werden können.

Die offensichtliche Verbindung mit Monadist wohl ein Artefakt der impliziten Beschränkungen, Applicativedie das Zusammentreffen von Aspekten ihrer jeweiligen monoiden Strukturen bewirken, ein glücklicher Zufall, der die Dualisierung leider nicht überlebt.

So wie eine Comonade auf einer Kategorie eine Monade auf C o p ist , ist ein Oplax-Monoid-Funktor C D ein lockerer Monoid-Funktor C o pD o p . Aber H a s k o p ist nicht monoidal geschlossen , und eine Co-Funktion , die keine Funktionsanwendung enthält, verdient den Namen kaum. Das Ergebnis wäre jedenfalls nicht sonderlich interessant:CCÖp CDCÖpDÖpHeinskÖpApplicative

class (Functor f) => CoMonoidal f where
    counit :: f () -> ()
    cozip :: f (a, b) -> (f a, f b)

Wir könnten uns stattdessen den Begriff "colax closed functor" vorstellen, der viel ähnlicher aussehen würde, Applicativewenn er existieren würde. Leider ist (meines Wissens) überhaupt keine geschlossene Kategorie: in H a s k entspricht Morphismen b a in H a s k o p , funktioniert aber nicht als internes Hom dort - da die Pfeile vertauscht sind, wäre stattdessen eine Art Ko-Funktion erforderlich, die wir für H a s k nicht allgemein definieren können .HeinskÖpnewtype Op b a = Op (a -> b)HeinskbeinHeinskÖpOp b aHeinsk

Wenn wir einfach so tun, als ob es für "colax closed functors" gäbe , und darüber hinaus so arbeiten würden, wie wir es uns naiv erhoffen, würde eine darauf basierende Zusammenarbeit wahrscheinlich so aussehen:HeinskApplicative

class (Functor f) => CoApplicative f where
    copure :: f a -> a
    coap :: (f a -> f b) -> f (a -> b)

Das Hinzufügen duplicate :: f a -> f (f a)zu copurewürde natürlich zu einer Komonade führen (vorausgesetzt, die Gesetze sind erfüllt). Aber es gibt keine offensichtliche Beziehung zwischen - coapwas auch immer es sein mag - und extend :: (f a -> b) -> f a -> f b. Vergleicht man die Typen, so zeigt sich, dass die Dualisierung auf unterschiedliche Weise abläuft: Die comonoidalen Strukturen liegen duplicateund coziphaben wenig miteinander oder damit zu tun coap(was wahrscheinlich ohnehin keinen Sinn macht), wohingegen liftA2 (,)und (<*>)gleichwertig sind und daraus abgeleitet werden können join.

Eine andere Möglichkeit der Dualisierung Applicative, die noch weniger mit Comonaden zu tun hat, besteht darin, kontravariante monoide Funktoren in Betracht zu ziehen:

class (Contravariant f) => ContraMonoidal f where
    contraunit :: f a
    contrazip :: f a -> f b -> f (Either a b)

HeinskÖpb <~ acontracurry :: (Either c b <~ a) -> (c <~ (b <~ a))contraapply :: b -> Either a (a <~ b)

HeinskCoApplicative

In einer monoidal geschlossenen Kategorie, die für die Dualisierung gastfreundlicher ist, haben Sie möglicherweise mehr Glück. Insbesondere glaube ich, dass beide Kleisli (Cont r)und die gegenüberliegende Kategorie monoidal geschlossen sind, so dass dies ein besserer Kontext sein könnte, um diese Ideen zu untersuchen.


Wenn Sie Ihre Antwort mit cstheory.stackexchange.com/a/22302/989 vergleichen , ist es überraschend, dass Sie Produkte nicht zu Summen verdoppeln. Sie haben natürlich Recht, dass Hask keine kategorischen Summen hat. Wenn Sie jedoch bereit sind, sich auf die Kategorie der Gesamtprogramme zu beschränken (wie in Agda), wollen wir so tun, als wäre es für den Moment festgelegt, dann verschwindet dieses Problem. (Ich sage nicht, dass Set ^ op monoidal geschlossen ist, aber ich vermute, dass das, was ich sage, dies impliziert).
Blaisorblade

8

In diesem Beitrag auf SO habe ich eine interessante Antwort gefunden - entscheidende Funktoren . Wenn wir die Pfeile ()durch Void, (,)durch Either und umkehren, erhalten wir:

class Functor f => Decisive f where
    nogood :: f Void -> Void
    orwell :: f (Either s t) -> Either (f s) (f t)

Der Blogbeitrag enthält auch einige Gesetze, die von entscheidenden Funkern befolgt werden.

Und jeder Comonadist auch Decisive:

instance Comonad c => Decisive c where
    nogood = counit
    orwell story = case counit story of
                     Left s  -> fmap (either id (const s)) story
                     Right t -> fmap (either (const t) id) story 

So passen entscheidende Funktoren zwischen Funktoren und Comonaden, so wie anwendbare Funktoren zwischen Funktoren und Monaden passen.


6

McBride und Patterson (Abschnitt 7) zeigen, dass ein anwendbarer Funktor, der auch als Redewendung bezeichnet wird, ein stark lockerer monoidaler Funktor ist . Sie suchen einen starken Colax-Monoidal-Functor, der auch als starker Oplax-Monoidal-Functor bekannt ist . Wie in einem Kommentar erwähnt, ist ein Oplax-Monoid-Funktor ein laxer Monoid-Funktor zwischen den entgegengesetzten Kategorien, der letztendlich eine comonoidale Version eines laxen Monoid-Funktors ist.

Zeichne die Diagramme, kehre die Pfeile um!

Ich müsste ein bisschen Zeit damit verbringen, die Details zu erarbeiten, um herauszufinden, was es ist, und um es in einen funktionalen Programmierbegriff zu übersetzen.


Aus irgendeinem Grund scheint der Standardbegriff "oplax monoidal functor" zu sein. Die Idee ist ein laxer monoidaler Funktor zwischen den entgegengesetzten Kategorien, der letztendlich eine comonoidale Version eines laxen monoidalen Funktors ist. Die Verwendung von "colax comonoidal" ist entweder überflüssig oder entspricht "lax monoidal".
CA McCann

Ich habe das "Mitmachen" übertrieben. Ich werde meine Antwort reparieren.
Dave Clarke
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.