rlm@2: #+TITLE: Monads in CS and Math rlm@2: #+BEGIN_HTML rlm@2:

rlm@2: {{{TITLE}}} rlm@2:

rlm@2: #+END_HTML rlm@2: rlm@2: The purpose of a /monad/ is to introduce a new data type into your rlm@2: language and to integrate it with existing types; a monad augments a rlm@2: pre-existing data type $A$, creating a new type $B$. rlm@2: rlm@2: When describing monads, I will use the following terminology: rlm@2: - Values of type $A$ are called *ordinary values*, because they belong rlm@2: to the pre-existing data type. rlm@2: - Values of type $B$ are called *monadic values*, because they rlm@2: belong to the type introduced by the monad. rlm@2: - A function $A\rightarrow B$ is called a *monadic function*; such rlm@2: functions accept regular values as input and return monadic values. rlm@2: rlm@2: rlm@2: rlm@2: A monad consists of rlm@2: two components for achieving this purpose: rlm@2: rlm@2: - A function that converts ordinary values into monadic values :: rlm@2: First, in order to create a new data type, each monad has an rlm@2: /upgrade function/ which systematically adds structure to values of rlm@2: the existing data type, $A$. Because the upgrade function produces rlm@2: enhanced values in a systematic way, the enhanced values constitute rlm@2: a sort of new data type, $B$. rlm@2: rlm@2: #+begin_quote rlm@2: $\text{upgrade}:A\rightarrow B$ rlm@2: #+end_quote rlm@2: rlm@2: - A function that enables monadic functions to accept monadic values :: Second, each monad has a /pipe function/ which is a rlm@2: protocol for combining a monadic function and a monadic value to rlm@2: produce a monadic value. The pipe function facilitates composition: rlm@2: notice that a collection of monadic functions $A\rightarrow B$ is composable only if they have been modified by the rlm@2: pipe function to become functions of type $B\rightarrow B$, otherwise their input and output types do not match. rlm@2: #+begin_quote rlm@2: $\text{pipe}:B\times B^A\rightarrow B$ rlm@2: #+end_quote rlm@2: rlm@2: #+srcname: intro rlm@2: #+begin_src clojure :results silent rlm@2: (ns categorical.monad) rlm@2: (use 'clojure.contrib.monads) rlm@2: #+end_src rlm@2: rlm@2: rlm@2: * Examples of monads rlm@2: ** The nondeterministic monad rlm@2: rlm@2: We'll implement nondeterministic programming by defining a monad =amb= rlm@2: that transforms ordinary deterministic functions into functions that ``ambiguously'' return zero or more rlm@2: values. rlm@2: rlm@2: #+srcname: stuff rlm@2: #+begin_src clojure :results silent rlm@2: (in-ns 'categorical.monad) rlm@2: rlm@2: ;; To implement nondeterministic programs, we'll use a lazy seq to represent a value which may be any one of the members of seq. rlm@2: rlm@2: (defmonad amb rlm@2: [ rlm@2: m-result (fn[& vals] (cons 'amb vals)) rlm@2: m-bind (fn[amb-seq f] (cons 'amb (map f (rest amb-seq)))) rlm@2: ] rlm@2: ) rlm@2: #+end_src rlm@2: rlm@2: #+begin_src clojure :results silent :tangle monad.clj :noweb yes rlm@2: <> rlm@2: <> rlm@2: #+end_src