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łuje main
. Jest też unsafePerformIO
oczywiście. Jeśli chcesz myśleć o Maybe
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.