Co to jest Comonad i jak są one przydatne?

16

Ostatnio odkurza moją wiedzę na temat działania Monad. Ja również zostały wprowadzone do pojęcia „Comonad” , który jest opisany jako odwrotny podwójny z monady . Nie mogę jednak owinąć głowy wokół tego.

Aby zrozumieć Monady, stworzyłem dla siebie własną analogię:

Monady można postrzegać jako „plan budowy przenośników wyrażeń”.

Aby zdefiniować nową Monadę (nowy rodzaj systemu przenośników taśmowych), musisz zdefiniować:

  1. Sposób na umieszczenie czegoś na przenośniku, np. „Uruchomienie” przenośnika. (Znany jako unitlub return)
  2. Sposób podłączenia maszyny (wyrażenie), która będzie częścią przenośnika taśmowego do przenośnika taśmowego. (Znany jako joinlub bindlub >>=).

(Trzecia operacja polega na zabraniu aktualnego przenośnika taśmowego, wyrzuceniu jego zawartości i uruchomieniu nowego przenośnika taśmowego znanego jako >>, ale jest on używany bardzo rzadko.)

Aby maszyny i przenośniki działały prawidłowo, musisz upewnić się, że:

  1. Jeśli położysz coś na przenośniku i przepuścisz przez maszynę, wydajność powinna być taka sama, jak w przypadku ręcznego przekazania przez maszynę. (Lewa tożsamość)
  2. Jeśli chcesz umieścić przenośnik taśmowy pomiędzy już istniejącym przenośnikiem taśmowym, nie powinieneś kończyć się przenośnikiem taśmowym, który ma na górze przenośnik taśmowy, a raczej pojedynczym, dłuższym przenośnikiem taśmowym. (Odpowiednia tożsamość)
  3. Nie powinno to mieć znaczenia dla wyniku, jeśli ręcznie użyjesz maszyny A, a następnie przekażesz wynik przez podłączoną do przenośnika BC lub jeśli użyjesz AB podłączonego do przenośnika, a następnie przekaż wynik ręcznie przez C. Innymi słowy: ((a >> = b) >> = c) powinien być taki sam jak (a >> = (b >> = c)) (asocjatywność)

Najprostszym przenośnikiem taśmowym byłby ten, który po prostu pobiera dane wejściowe i zawsze przechodzi do następnego wyrażenia. Oto czym jest „rurociąg”.

Inną możliwością jest przepuszczenie go przez następną maszynę, tylko jeśli warunek jest spełniony dla wartości. Oznacza to, że jeśli w niektórych wyrażeniach pośrednich wartość zmieni się na coś, co nie jest już dozwolone, wówczas pozostałe wyrażenia zostaną pominięte. Tak właśnie robi monada „Może” w Haskell.

Możesz także wykonać inne fantazyjne warunkowe reguły kopiowania / zmiany wartości przed lub po przekazaniu ich do komputera. Przykład: Parsery (tutaj, jeśli wyrażenie zwraca wynik „błąd”, wartość sprzed wyrażenia jest używana jako wynik).

Oczywiście analogia nie jest idealna, ale mam nadzieję, że dobrze ilustruje działanie monad.

Mam jednak problem z odwróceniem tej analogii, aby zrozumieć Comonady. Wiem z niewielkiej ilości informacji, które znalazłem w Internecie, które definiuje Comonad:

  • extract, Który jest swego rodzaju odwrocie return, to znaczy, że przyjmuje wartość wyjścia z Comonad.
  • duplicate, co jest swego rodzaju odwrotnością join, to znaczy tworzy dwie Comonady z jednego.

Ale w jaki sposób można utworzyć instancję Comonadu, jeśli jesteśmy w stanie ją wydobyć lub zduplikować? I w jaki sposób można z nich korzystać? Widziałem ten niesamowity projekt i rozmowę na jego temat (której niestety bardzo mało rozumiałem), ale nie jestem pewien, która część funkcjonalności jest dokładnie dostarczana przez Comonad.

Co to jest Comonad? Do czego są przydatne? Jak można ich używać? Czy są jadalne?

Qqwy
źródło
2
„w jaki sposób można utworzyć instancję Comonadu, jeśli jesteśmy w stanie ją wyodrębnić lub zduplikować?” - Odpowiem na twoje pytanie pytaniem: w jaki sposób można zużyć monadę, jeśli jesteś w stanie podnieść do nich wartości i obliczyć sekwencje?
Benjamin Hodgson,
1
„Maszyną na końcu taśmy przenośnika” (na bok: nie uważam analogii za przydatne w przypadku monad) IOmonady jest system uruchomieniowy Haskell, który wywołuje main. Jest też unsafePerformIOoczywiście. Jeśli chcesz myśleć o Maybemonadzie jako o „maszynie na końcu przenośnika”, możesz użyć maybe.
Benjamin Hodgson
1
Ale odwracając swoje objaśnienie, jeśli chcesz stworzyć wartość comonadyczną na początku łańcucha cobindaplikacji, musi istnieć funkcja, która robi coś użytecznego z wewnętrzną reprezentacją twojej comonad.
Benjamin Hodgson,
2
określone wystąpienie comonad lub monad może wyraźnie mieć więcej funkcjonalności niż jest to wymagane tylko do zaimplementowania klas
jk.
2
Nie dlatego, że to będzie pomocne, jeśli nie podejście to pytanie ze strony Category-teoretyczna / matematyczny, ale chciałem podkreślić, że comonad nie jest odwrotnością ale raczej podwójny z monady.
Jörg W Mittag

Odpowiedzi:

11

Comonada jest, podobnie jak monada, strukturą matematyczną w teorii kategorii. Dodatkowy przedrostek jest tam bardzo często używany do oznaczania „odwrotności”, jak to ująłeś (chociaż nie sądzę, by czysti matematycy zgadzali się co do wyboru słowa).

W teorii kategorii znajdują się categories, które są krótko zestawione objects(wszelkiego rodzaju lub rodzaju, struktura wewnętrzna nie ma znaczenia) i niektóre arrowsmiędzy tymi obiektami. Aby coś było kategorią, strzałki muszą być zgodne z niektórymi prawami (tożsamość lewa / prawa i skojarzenie), ale nie jest to tak naprawdę ważne.

Teraz teoria kategorii jest zarówno bardzo abstrakcyjna / trudna do zrozumienia, jak i ogromna. Przejście tego zajmuje dużo czasu (i nie studiowałem tego formalnie, znam tylko niektóre podstawy), ale istnieje pojęcie, które nazywa się dual. Zasadniczo, dla każdej kategorii możesz zbudować, opposite categoryrobiąc to samo, ale „odwracając wszystkie strzałki”. Jest to bardzo naiwna definicja, ale trudno jest ją streścić. Podwójność czegoś w kategorii C jest w zasadzie taka sama w przeciwnej kategorii C_op (jeszcze boli cię głowa?)

W każdym razie, jeśli masz monadę nad jakąś kategorią (a kategoria może na przykład być kategorią, w której obiekty są typami w jakimś języku programowania, a strzałki są funkcjami między typami), to comonada jest w zasadzie tym samym, tylko ty odwróciłem wszystkie strzałki (w tym przypadku coś w rodzaju odwrócenia sygnatur funkcji).

Bardziej „praktyczny” opis (choć nie SUPER praktyczny) można znaleźć w tej dyskusji między Erikiem Meijerem i Brianem Beckmanem, w której omawiają pojęcie dualności i tego, jak Erik zajął się „odwracaniem strzał” IEnumerable<T>w C #, gdy tworzenie reaktywnego frameworka i IObservable<T>(o ile mogę powiedzieć, i cieszę się, że mogę to poprawić, w zasadzie jest to instancja comonad listy).

Innym praktycznym przykładem comonadów wspomnianych w filmie jest Task<T>typ .NET, gdzie Task<U> ContinueWith<U>(Func<Task<T>, U>)byłby dual z bind(lub SelectManyjak to się nazywa w C #)

sara
źródło