06 października 2010

Monady w Clojure - wstęp do maybe-m - kontynuacja i Teoria kategorii w podstawach informatyki na MIMUWie

Wczoraj opisywałem moje dokonania w (przynajmniej częściowym) zrozumieniu działania monad w Clojure reprezentowanych przez monadę maybe-m. Dzisiaj wysłuchałem 2 prezentacji wokół tego tematu i przeczytałem artykuł o monadach na przykładzie ich realizacji w Pythonie i Haskellu. Nic specjalnie odkrywczego, ale coś mnie tknęło, aby jeszcze sprawdzić, czy i jak definiuje się monady na bazie mojej niewielkiej wiedzy w tym temacie.

Zacząłem od prostej modyfikacji monady maybe-m, w której wartość nieprawidłowa nil kończy przetwarzanie. Postanowiłem wprowadzić pewne urozmaicenie, które jakkolwiek nie wprowadza niczego specjalnie odkrywczego w samym działaniu monady, to może jednak uprościć ich zrozumienie.

Załóżmy taką definicję monady nothing-m, której zadaniem jest podmiana wartości nieprawidłowej.

(defmonad nothing-m
   "Monad describing computations with possible failures which are
    represented by nil. The failure is changed into :nothing.
    This monad is based upon maybe-m monad from Clojure's c.c.monads
    Author: Jacek Laskowski"
   [m-result (fn [v] v)
    m-bind   (fn [mv f]
               (if (nil? mv) (f :nothing) (f mv)))
    ])
Każda monada musi dostarczać w swojej podstawowej realizacji 2 metody - m-result oraz m-bind. Pierwsza, m-result (trafniej byłoby raczej nazywać ją m-inject) opakowuje wartość w wartość monadyczną. Druga, m-bind, to funkcja (prawie)odwrotna do m-result, bo częściowo rozpakowuje przekazaną wartość monadyczną i działa na niej funkcją. Obie realizują pewien kontrakt monadyczny, o którym jeszcze kiedyś tam napiszę (jak sam zrozumiem temat :)).

W mojej realizacji kontraktu monadycznego, każdorazowe napotkanie wartości specjalnej (obecnie tylko nil, ale możnaby wyobrazić sobie cały ich zbiór) kończy się zwróceniem :nothing.

user=> (domonad nothing-m
  [m (do (println 1) :m)
   n (do (println 2) nil)
   o (do (println 3) :o)
   p (do (println 4) nil)
   r (do (println 5) :r)]
    (println m n o p r))
1
2
3
4
5
:m :nothing :o :nothing :r
nil
Proste, co? Przy tej realizacji założeń - podmiana wartości specjalnej na podaną - przypomina mi działanie aspektów AroundInvoke, które mogą wykonać dodatkowe operacje, np. podmiana wyniku działania funkcji na zadany bez zmiany tejże. Dla niektórych zapewne bliższe to jest wzorcowi Dekorator.

A skoro o monadach, to zajrzałem na przedmioty oferowane na wydziale Matematyki, Informatyki i Mechaniki Uniwersytetu Warszawskiego (MIMUW) pod kątem tych, które poruszają tematykę programowania funkcyjnego z naciskiem na coś strawnego jak Clojure albo Erlang, ale nic co przypadłoby mi do gustu. Wpadł mi do głowy pomysł, aby sprawdzić teorię kategorii i jakież było moje zdziwienie, kiedy trafiłem na przedmiot Teoria kategorii w podstawach informatyki. Pomyślałem sobie, że może by tak odświeżyć pamięć i zamiast czytać, możnaby posłuchać, a jeszcze byłaby możliwość porozmawiać, więc napisałem do prof. Andrzeja Tarleckiego. Nie upłynął kwadrans, a ja już miałem odpowiedź!

Szanowny Panie,

Ostatecznie ustalony termin zajec to:

piatki, 14.00-15.30, sala 5870 (pierwsze zajecia w tym tygodniu, 8/10)
wtorki, 12.15-13.45, sala dopiero bedzie ustalona.

Prowizoryczna strona wykladu:
http://www.mimuw.edu.pl/~tarlecki/teaching/ct/index.html

O ile mi wiadomo, wyklady uniwersyteckie sa otwarte - wiec jesli ma Pan ochote, to zapraszam. Aha, zajecia beda prowadzone w jezyku angielskim (przynajmniej jeden student jest obcokrajowcem).

Z powazaniem,
Andrzej Tarlecki


Akurat w piątek o 14:00 mam czas, aby zajrzeć, więc dlaczego nie?!