+different types. But it's possible to make the connection between
+monads and monoids much closer. This is discussed in [[Advanced Notes/Monads in Category Theory]]. See also <http://www.haskell.org/haskellwiki/Monad_Laws>.
+
+Here are some papers that introduced monads into functional programming:
+
+* [Eugenio Moggi, Notions of Computation and Monads](http://www.disi.unige.it/person/MoggiE/ftp/ic91.pdf): Information and Computation 93 (1).
+
+* [Philip Wadler. Monads for Functional Programming](http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf):
+in M. Broy, editor, *Marktoberdorf Summer School on Program Design Calculi*, Springer Verlag, NATO ASI Series F: Computer and systems sciences, Volume 118, August 1992. Also in J. Jeuring and E. Meijer, editors, *Advanced Functional Programming*, Springer Verlag, LNCS 925, 1995. Some errata fixed August 2001.
+ The use of monads to structure functional programs is described. Monads provide a convenient framework for simulating effects found in other languages, such as global state, exception handling, output, or non-determinism. Three case studies are looked at in detail: how monads ease the modification of a simple evaluator; how monads act as the basis of a datatype of arrays subject to in-place update; and how monads can be used to build parsers.
+
+* [Philip Wadler. The essence of functional programming](http://homepages.inf.ed.ac.uk/wadler/papers/essence/essence.ps):
+invited talk, *19'th Symposium on Principles of Programming Languages*, ACM Press, Albuquerque, January 1992.
+ This paper explores the use monads to structure functional programs. No prior knowledge of monads or category theory is required.
+ Monads increase the ease with which programs may be modified. They can mimic the effect of impure features such as exceptions, state, and continuations; and also provide effects not easily achieved with such features. The types of a program reflect which effects occur.
+ The first section is an extended example of the use of monads. A simple interpreter is modified to support various extra features: error messages, state, output, and non-deterministic choice. The second section describes the relation between monads and continuation-passing style. The third section sketches how monads are used in a compiler for Haskell that is written in Haskell.
+
+There's a long list of monad tutorials on the [[Offsite Reading]] page. Skimming the titles makes me laugh.
+
+In the presentation we gave above, which is the usual one in functional programming, we took unit/return and bind as the primitive operations. From these a number of other general monad operations can be derived. It's also possible to take some of the others as primitive, and define for example bind in terms of them. This is discussed some in the [[Advanced Notes/Monads in Category Theory]].
+
+
+Here are some of the specifics. You don't have to master these; they're collected here for your reference.
+
+You may sometimes see:
+
+ m >> n
+
+That just means:
+
+ m >>= fun _ -> n
+
+that is:
+
+ bind m (fun _ -> n)
+
+You could also do `bind m (fun x -> n)`; we use the `_` for the function argument to be explicit that that argument is never going to be used.
+
+The `lift` operation we asked you to define for last week's homework is a common operation. The second argument to `bind` converts 'a values into `b m values---that is, into instances of the monadic type. What if we instead had a function that merely converts `a values into `b values, and we want to use it with our monadic type. Then we "lift" that function into an operation on the monad. For example:
+
+ # let even x = (x mod 2 = 0);;
+ val g : int -> bool = <fun>
+
+`even` has the type int -> bool. Now what if we want to convert it into an operation on the option/maybe monad?
+
+ # let lift g = fun m -> bind m (fun x -> Some (g x));;
+ val lift : ('a -> 'b) -> 'a option -> 'b option = <fun>
+
+`lift even` will now be a function from `int option`s to `bool option`s. We can
+also define a lift operation for binary functions:
+
+ # let lift2 g = fun m n -> bind m (fun x -> bind n (fun y -> Some (g x y)));;
+ val lift2 : ('a -> 'b -> 'c) -> 'a option -> 'b option -> 'c option = <fun>
+
+`lift (+)` will now be a function from `int option`s and `int option`s to `int option`s. This should look familiar to those who did the homework.
+
+The `lift` operation (just `lift`, not `lift2`) is sometimes also called the `map` operation. (In Haskell, they say `fmap` or `<$>`.) And indeed when we're working with list monad, `lift f` is exactly `List.map f`!
+
+Wherever we have a well-defined monad, we can define a lift/map operation for that monad. The examples above used `Some (g x)` and so on; in the general case we'd use `unit (g x)`, using the pre-defined `unit` operation for the monad we're working with.
+
+In general, any lift/map operation can be relied on to satisfy these laws:
+
+ * lift id = id
+ * lift (compose f g) = compose (lift f) (lift g)
+
+where id is `fun x -> x` and `compose a b` is `fun x -> a (b x)`. If you think about the special case of the map operation on lists, this should make sense. `List.map id lst` should give you back `lst` again. And you'd expect these
+two computations to give the same result:
+
+ List.map (fun x -> f (g x)) lst
+
+ List.map f (List.map g lst)
+
+Another general monad operation is called `ap` in Haskell---short for "apply." (They also use `<*>`, but who can remember that?) This works like this:
+
+ ap [f] [x; y] = [f x; f y]
+ ap (Some f) (Some x) = Some (f x)
+
+and so on. Here are the laws that any ap operation can be relied on to satisfy:
+
+ ap (unit id) v = v
+ ap (ap (ap (return compose) u) v) w = ap u (ap v w)
+ ap (unit f) (unit x) = unit (f x)
+ ap u (unit y) = ap (unit (fun f -> f y)) u
+
+Another general monad operation is called `join`. This is the operation that takes you from an iterated monad to a single monad. Remember when we were explaining the `bind` operation for the list monad, there was a step where
+we went from:
+
+ [[1]; [1;2]; [1;3]; [1;2;4]]
+
+to:
+
+ [1; 1; 2; 1; 3; 1; 2; 4]
+
+That is the `join` operation.
+
+All of these operations can be defined in terms of `bind` and `unit`; or alternatively, some of them can be taken as primitive and `bind` can be defined in terms of them. Here are various interdefinitions:
+
+ lift f m = ap (unit f) m
+ lift2 f m n = ap (lift f m) n = ap (ap (unit f) m) n
+ ap m n = lift2 id m n
+ lift f m = m >>= compose unit f
+ lift f m = ap (unit f) m
+ join m2 = m2 >>= id
+ m >>= f = join (lift f m)
+ m >> n = m >>= (fun _ -> n)
+ m >> n = lift2 (fun _ -> id) m n
+