
On Aug 3, 2010, at 2:51 PM, aditya siram wrote:
I am looking for suggestions on how to introduce the concept and its implications. I'd also like to include a section on why monads exist and why we don't really see them outside of Haskell.
Start with functors (things that attach values/functions/functors to values in an algebra). Move on to applicative functors (functors that can interpret the thing that is getting things attached to it). Move on to monads (applicative functors where you can explicitly control the order of evaluation/interpretation). Monads exist because every adjunction generates a monad, every monad generates an adjunction, and adjunctions are everywhere. Any time you can put things "next to" each other, you can create a monad that captures the notion. A monad corresponds to putting things to the left (at least syntactically) of the "main" object. A comonad corresponds to putting things to the right of the main object (assuming we observe the "monad = left" convention). There are monads every where. They typically carry around extra structure in other programming languages. That is, you can't quantify over them, because they have been specialized. For example, any language that has a "map" function automatically supports monadic computation, in virtue of the fact that map accepts one argument functions. (I.e., functions where the function's name goes on the left, and the argument goes on the right) sub minus_one = { $x = @_[0]; return $x * (-1); } return map minus_one map double map square [1.. 10] (I hardly remember Perl now though...) Notice that you can't change the order of the operations without changing the semantics. This is strictly a monadic computation, in Perl, PHP, etc. Ruby is a little nicer than Perl, since it allows functors other than lists. If you make a class a member of the Enumerate mixin, you can call .each on the class's instances, give it a monadic (one argument) function, and it returns a new functor over the relevant type of object. funky_tree.each { node | node.value.square.double.minus_one } (in the function composition case, or ... in the "structurally moandic" case:) funky_tree.each { node | node.value } .each { value | square value } .each { square' | double square' } .each { doubled | minus_one double } I doubt this is legal Ruby either. It's been a few years since I touched it.