Każda monada jest również funktorem aplikacyjnym, a każdy funktor aplikacyjny jest funktorem. Ponadto każdy comonad jest funktorem. Czy istnieje podobna koncepcja między comonadami i funktorami, coś w rodzaju funktora kooperacyjnego i jakie są jego właściwości?
Aktualizacja: Byłbym również zainteresowany możliwymi zastosowaniami takiej koncepcji.
ct.category-theory
monad
applicative
comonad
Petr Pudlák
źródło
źródło
Odpowiedzi:
Po pierwsze:
Jest to prawdą w kontekście Haskella, ale (czytając
Applicative
jako „silny luźny funktor monoidalny”) nie ogólnie, z dość trywialnego powodu, że można mieć „aplikacyjne” funktory między różnymi kategoriami monoidalnymi, podczas gdy monady (i comonady) są endofunkorami .Ponadto identyfikacja za
Applicative
pomocą silnych luźnych funktorów monoidalnych jest nieco myląca, ponieważ uzasadnienie nazwy (i podpisu typu(<*>)
) wymaga funktora między zamkniętymi kategoriami monoidalnymi, który zachowuje zarówno strukturę monoidalną, jak i hom wewnętrzny . Można to prawdopodobnie nazwać „luźnym zamkniętym funktorem monoidalnym”, z tym wyjątkiem, że funktor między monoidalnymi zamkniętymi kategoriami, który zachowuje jedną właściwość, zachowuje drugą w oczywisty sposób . PonieważApplicative
opisuje tylko endofunkcje na Hask, zachowujące monoidalną strukturę(,)
, jego instancje automatycznie zyskują wiele właściwości, w tym ich wytrzymałość , którą można w ten sposób uniknąć.Pozorny związek z tym
Monad
jest prawdopodobnie artefaktem ukrytych ograniczeńApplicative
powodowania zbieżności aspektów ich odpowiednich struktur monoidów, szczęśliwy zbieg okoliczności, który niestety nie przeżywa dualizacji.Tak jak comonada w kategorii jest monadą w C o p , tak opaksoryczny funktor monoidalny C → D jest luźnym funktorem monoidalnym C o p → D o p . Ale H a s k o p nie jest monoidalnie zamknięty , a nazwa ko- nie zawierająca aplikacji funkcji nie zasługuje na miano. W każdym razie wynik nie byłby wyjątkowo interesujący:C Cop C→D Cop→Dop Haskop
Applicative
Zamiast tego moglibyśmy wyobrazić sobie pojęcie „funktora zamkniętego colaxa”, który wyglądałby znacznie bardziej,Haskop Hask b→a Haskop Hask
Applicative
gdyby istniał. Niestety, wcale nie jest (według mojej najlepszej wiedzy) kategorią zamkniętą: w H a s k odpowiada morfizmom b → a w H a s k o p , ale nie działa jako wewnętrzny hom tam - ponieważ strzałki są odwrócone, zamiast tego wymagana byłaby jakaś funkcja, której nie możemy ogólnie zdefiniować dla H a s k .newtype Op b a = Op (a -> b)
Op b a
Gdybyśmy po prostu udawali, że „funktory zamknięte colax” istniały dla , a ponadto działały w sposób, na jaki naiwnie mamy nadzieję, że tak się stanie, koegzystencja na tym prawdopodobnie wyglądałaby tak:Hask
Applicative
Oczywiście, dodanie
duplicate :: f a -> f (f a)
docopure
tego spowodowałoby comonadę (zakładając, że prawa są spełnione). Ale nie ma oczywistego związku między -coap
czymkolwiek by to nie było - aextend :: (f a -> b) -> f a -> f b
. Porównując typy, staje się jasne, że dualizacja odbywa się na różne sposoby: struktury comonoidalne leżące u podstawduplicate
icozip
mające niewiele wspólnego ze sobą lub z nimicoap
(co prawdopodobnie i tak nie ma sensu),liftA2 (,)
a jednocześnie(<*>)
są równoważne i można je wyprowadzićjoin
.Innym możliwym sposobem dualizacji
Applicative
, który ma jeszcze mniej wspólnego z comonadami, jest rozważenie przeciwstawnych funktorów monoidalnych:Działa to jednak z tymi samymi problemami, co powyżej, a mianowicie, że nie jest kategorią zamkniętą. Gdyby tak było, mielibyśmy jakiś rodzaj takie, że możemy napisać funkcje, jak i i tak dalej, że faktycznie pracował zgodnie z oczekiwaniami.Haskop
b <~ a
contracurry :: (Either c b <~ a) -> (c <~ (b <~ a))
contraapply :: b -> Either a (a <~ b)
CoApplicative
Jednak w monoidalnej zamkniętej kategorii, bardziej gościnnej dla dualizacji, możesz mieć więcej szczęścia. W szczególności uważam, że obie
Kleisli (Cont r)
i ich przeciwna kategoria są zamknięte monoidalnie, więc może to być lepszy kontekst do zbadania tych pomysłów.źródło
W tym poście na SO znalazłem ciekawą odpowiedź - decydujące funktory . Jeśli możemy zastąpić
()
przezVoid
,(,)
przezEither
i odwrócenie strzałki, otrzymujemy:Wpis na blogu zawiera również niektóre przepisy, do których stosują się decydenci.
I każdy
Comonad
jest równieżDecisive
:Tak więc decydujące funktory mieszczą się między funktorami a comonadami, tak jak funktory aplikacyjne mieszczą się między funktorami a monadami.
źródło
McBride i Patterson (sekcja 7) pokazują, że aplikacyjny funktor, znany również jako idiom, jest silnym luźnym funktorem monoidalnym . Szukasz silnego funktora monoidalnego colax, znanego również jako silny monoidalny funktor opaksowy . Jak wspomniano w komentarzu, opoidalny funktor monoidalny jest luźnym funktorem monoidalnym pomiędzy przeciwnymi kategoriami, co ostatecznie stanowi comonoidalną wersję luźnego funktora monoidalnego.
Narysuj schematy, odwróć strzałki!
Musiałbym poświęcić trochę czasu na wypracowanie szczegółów, aby zobaczyć, co to jest, i przełożyć je na funkcjonalne pojęcie programowania.
źródło