Obecnie dużo mówi się o monadach. Przeczytałem kilka artykułów / postów na blogu, ale nie mogę posunąć się za daleko z ich przykładami, aby w pełni zrozumieć tę koncepcję. Powodem jest to, że monady są pojęciem języka funkcjonalnego, a zatem przykłady są w językach, z którymi nie pracowałem (ponieważ nie użyłem języka funkcjonalnego dogłębnie). Nie mogę zrozumieć składni na tyle głęboko, aby w pełni śledzić artykuły ... ale mogę powiedzieć, że jest tam coś, co warto zrozumieć.
Znam jednak C # całkiem dobrze, w tym wyrażenia lambda i inne funkcje funkcjonalne. Wiem, że C # ma tylko podzbiór cech funkcjonalnych, więc może monady nie mogą być wyrażone w C #.
Czy na pewno można jednak przekazać tę koncepcję? Przynajmniej mam taką nadzieję. Być może można przedstawić przykład C # jako fundament, a następnie opisać to, co programista C # by życzyć mógł zrobić stamtąd, ale nie może, ponieważ język pozbawiony cech funkcjonalnych programowania. Byłoby to fantastyczne, ponieważ oddawałoby intencje i zalety monad. Oto moje pytanie: jakie jest najlepsze wytłumaczenie dla monad dla programisty C # 3?
Dzięki!
(EDYCJA: Nawiasem mówiąc, wiem, że są już co najmniej 3 pytania „co to jest monada” na SO. Jednak mam z nimi ten sam problem ... więc to pytanie jest potrzebne imo, ze względu na programistę C # skup się. Dzięki.)
Odpowiedzi:
Większość tego, co robisz w programowaniu przez cały dzień, to łączenie niektórych funkcji razem, aby tworzyć z nich większe funkcje. Zwykle masz nie tylko funkcje w zestawie narzędzi, ale także inne rzeczy, takie jak operatory, przypisania zmiennych i tym podobne, ale ogólnie twój program łączy wiele „obliczeń” z większymi obliczeniami, które zostaną połączone razem.
Monada to jakiś sposób na wykonanie tego „łączenia obliczeń”.
Zwykle twoim najbardziej podstawowym „operatorem” do łączenia dwóch obliczeń jest
;
:Kiedy to mówisz, masz na myśli „najpierw zrób
a
, a potem zróbb
”. Rezultatema; b
jest po prostu ponownie obliczenie, które można łączyć z wieloma innymi rzeczami. Jest to prosta monada, jest to sposób na połączenie małych obliczeń z większymi.;
Mówi „zrobić coś po lewej stronie, a następnie zrobić coś po prawej stronie”.Inną rzeczą, którą można postrzegać jako monadę w językach obiektowych, jest
.
. Często znajdziesz takie rzeczy:W
.
zasadzie oznacza „ocenia obliczeń po lewej stronie, a następnie wywołać metodę z prawej strony na skutek, że”. Jest to inny sposób łączenia funkcji / obliczeń razem, nieco bardziej skomplikowany niż;
. Koncepcja łączenia łańcuchów razem.
jest monadą, ponieważ jest to sposób na połączenie dwóch obliczeń razem w nowe obliczenie.Inną dość powszechną monadą, która nie ma specjalnej składni, jest ten wzorzec:
Zwracana wartość -1 oznacza błąd, ale nie ma prawdziwego sposobu na usunięcie tego sprawdzania błędów, nawet jeśli masz wiele wywołań API, które musisz połączyć w ten sposób. Jest to w zasadzie kolejna monada, która łączy wywołania funkcji według reguły „jeśli funkcja po lewej zwróciła -1, sami zwróć -1, w przeciwnym razie wywołaj funkcję po prawej”. Gdybyśmy mieli operatora,
>>=
który to zrobił, moglibyśmy po prostu napisać:Sprawiłoby, że rzeczy byłyby bardziej czytelne i pomogłyby wyodrębnić nasz specjalny sposób łączenia funkcji, abyśmy nie musieli powtarzać się od nowa.
Istnieje wiele innych sposobów łączenia funkcji / obliczeń, które są użyteczne jako ogólny wzorzec i mogą być wyodrębnione w monadzie, umożliwiając użytkownikowi monady napisanie znacznie bardziej zwięzłego i przejrzystego kodu, ponieważ cała księgowość i zarządzanie używane funkcje są wykonywane w monadzie.
Na przykład powyższe
>>=
można rozszerzyć na „sprawdzanie błędów, a następnie wywoływanie prawej strony gniazda, które otrzymaliśmy jako dane wejściowe”, dzięki czemu nie musimy jawnie określaćsocket
wiele razy:Definicja formalna jest nieco bardziej skomplikowana, ponieważ musisz się martwić, jak uzyskać wynik jednej funkcji jako danych wejściowych do następnej, jeśli ta funkcja wymaga tego wejścia i ponieważ chcesz się upewnić, że połączone funkcje pasują do sposób, w jaki próbujesz połączyć je w swojej monadzie. Ale podstawowa koncepcja polega na sformalizowaniu różnych sposobów łączenia funkcji.
źródło
;
przykładzie: jakie obiekty / typy danych są;
mapowane? (PomyślList
mapyT
doList<T>
) Jak;
map morfizmów / funkcje między obiektami / typów danych? Co to jestpure
,join
,bind
za;
?Minął rok odkąd opublikowałem to pytanie. Po opublikowaniu, zagłębiałem się w Haskell przez kilka miesięcy. Bardzo mi się podobało, ale odłożyłem go na bok, gdy byłem gotowy zagłębić się w Monady. Wróciłem do pracy i skupiłem się na technologiach wymaganych przez mój projekt.
Ostatniej nocy przyszedłem i ponownie przeczytałem te odpowiedzi. Co najważniejsze , ponownie przeczytałem konkretny przykład C # w komentarzach tekstowych filmu Briana Beckmana , o którym ktoś wspomniał powyżej . To było tak całkowicie jasne i pouczające, że postanowiłem opublikować go bezpośrednio tutaj.
Ze względu na ten komentarz, nie tylko czuję się jak rozumiem dokładnie co Monady są ... Zdaję sobie sprawę, jakie faktycznie napisał kilka rzeczy w C #, które są Monadami… lub przynajmniej bardzo blisko, i staram się rozwiązać te same problemy.
Tak więc, oto komentarz - to wszystko jest bezpośredni cytat z komentarza tutaj przez Sylvan :
źródło
Monada jest zasadniczo odroczonym przetwarzaniem. Jeśli próbujesz napisać kod, który ma skutki uboczne (np. I / O) w języku, który im na to nie pozwala i pozwala tylko na czyste obliczenia, jednym uchyleniem jest powiedzenie: „Ok, wiem, że nie zrobisz efektów ubocznych dla mnie, ale czy możesz obliczyć, co by się stało, gdybyś zrobił? ”
To trochę oszustwo.
To wyjaśnienie pomoże ci zrozumieć ogólny obraz monad, ale diabeł tkwi w szczegółach. Jak dokładnie należy obliczyć konsekwencje? Czasami to nie jest ładne.
Najlepszym sposobem przedstawienia przeglądu tego, jak ktoś przyzwyczaił się do programowania imperatywnego, jest powiedzenie, że umieszcza cię w DSL, w którym operacje wyglądające syntaktycznie jak to, do czego przywykłeś poza monadą, jest używane zamiast do zbudowania funkcji, która by działała co chcesz, jeśli możesz (na przykład) zapisać plik wyjściowy. Prawie (ale nie tak naprawdę), jakbyś budował kod w ciągu, aby później go sprawdzić.
źródło
Maybe
iEither e
) oraz zarządzania stanem (State s
,ST s
) wydają mi się szczególnymi przypadkami „Proszę obliczyć, co by się stało, gdybyś zrobił [efekty uboczne dla mnie]”. Innym przykładem może być niedeterminizm ([]
).Jestem pewien, że inni użytkownicy opublikują dogłębnie, ale uznałem ten film za pomocny, ale powiem, że nadal nie jestem zbyt biegły w koncepcji, żebym mógł (lub powinien) zacząć rozwiązywać problemy intuicyjnie z Monadami.
źródło
Możesz myśleć o monadzie jako języku C #,
interface
który klasy muszą zaimplementować . Jest to pragmatyczna odpowiedź, która ignoruje całą teoretyczną matematykę stojącą za tym, dlaczego chcesz mieć te deklaracje w swoim interfejsie i ignoruje wszystkie powody, dla których chcesz mieć monady w języku, który próbuje uniknąć skutków ubocznych, ale uważam, że to dobry początek, ponieważ ktoś, kto rozumie interfejsy (C #).źródło
Zobacz moją odpowiedź na „Co to jest monada?”
Zaczyna się od motywującego przykładu, przechodzi przez przykład, czerpie przykład monady i formalnie definiuje „monadę”.
Nie zakłada znajomości programowania funkcjonalnego i używa pseudokodu ze
function(argument) := expression
składnią z najprostszymi możliwymi wyrażeniami.Ten program w C # jest implementacją monady pseudokodu. (Dla porównania:
M
jest konstruktorem typu,feed
jest operacją „powiązania” i operacjąwrap
„powrotu”).źródło