+different types. But it's possible to make the connection between
+monads and monoids much closer. This is discussed in [Monads in Category
+Theory](/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 follows the functional programming conventions---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. The [Monads in Category
+Theory](/advanced_notes/monads_in_category_theory) notes do so, for example.
+
+Here are some of the specifics. You don't have to master these; they're collected here for your reference.
+
+You may sometimes see:
+
+ u >> v
+
+That just means:
+
+ u >>= fun _ -> v
+
+that is:
+
+ bind u (fun _ -> v)
+
+You could also do `bind u (fun x -> v)`; 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 u -> bind u (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 u v -> bind u (fun x -> bind v (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 the 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 specific `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 f g` is `fun x -> f (g 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) u = u
+ ap (ap (ap (return compose) u) v) w = ap u (ap v w)
+ ap (unit f) (unit x) = unit (f x)
+ ap u (unit x) = ap (unit (fun f -> f x)) 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 u = ap (unit f) u
+ lift2 f u v = ap (lift f u) v = ap (ap (unit f) u) v
+ ap u v = lift2 id u v
+ lift f u = u >>= compose unit f
+ lift f u = ap (unit f) u
+ join m2 = m2 >>= id
+ u >>= f = join (lift f u)
+ u >> v = u >>= (fun _ -> v)
+ u >> v = lift2 (fun _ -> id) u v
+