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ć:
- Sposób na umieszczenie czegoś na przenośniku, np. „Uruchomienie” przenośnika. (Znany jako
unit
lubreturn
)- Sposób podłączenia maszyny (wyrażenie), która będzie częścią przenośnika taśmowego do przenośnika taśmowego. (Znany jako
join
lubbind
lub>>=
).(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:
- 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ść)
- 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ść)
- 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 odwrociereturn
, 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?
IO
monady jest system uruchomieniowy Haskell, który wywołujemain
. Jest teżunsafePerformIO
oczywiście. Jeśli chcesz myśleć oMaybe
monadzie jako o „maszynie na końcu przenośnika”, możesz użyćmaybe
.cobind
aplikacji, musi istnieć funkcja, która robi coś użytecznego z wewnętrzną reprezentacją twojej comonad.Odpowiedzi:
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 zestawioneobjects
(wszelkiego rodzaju lub rodzaju, struktura wewnętrzna nie ma znaczenia) i niektórearrows
mię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 category
robią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 iIObservable<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, gdzieTask<U> ContinueWith<U>(Func<Task<T>, U>)
byłby dual zbind
(lubSelectMany
jak to się nazywa w C #)źródło
Z mojego małego zrozumienia, comonad jest maszyną Rube Goldberg do wykonywania post-docs:
http://www.willamette.edu/~fruehr/haskell/evolution.html
... przepraszam, nie mogłem się oprzeć.
źródło