material within the sentence can satisfy presuppositions for other
material that otherwise would trigger a presupposition violation; but,
not surprisingly, these refinements will require some more
-sophisticated techniques than the super-simple option monad.]
+sophisticated techniques than the super-simple Option monad.]
Monads in General
So `unit` is a way to put something inside of a monadic box. It's crucial
to the usefulness of monads that there will be monadic boxes that
- aren't the result of that operation. In the option/maybe monad, for
+ aren't the result of that operation. In the Option/Maybe monad, for
instance, there's also the empty box `None`. In another (whimsical)
example, you might have, in addition to boxes merely containing integers,
special boxes that contain integers and also sing a song when they're opened.
* Thirdly, an operation that's often called `bind`. As we said before, this is another
unfortunate name: this operation is only very loosely connected to
- what linguists usually mean by "binding." In our option/maybe monad, the
+ what linguists usually mean by "binding." In our Option/Maybe monad, the
bind operation is:
let bind u f = match u with None -> None | Some x -> f x;;
The guts of the definition of the `bind` operation amount to
specifying how to unbox the monadic value `u`. In the `bind`
- operator for the option monad, we unboxed the monadic value by
+ operator for the Option monad, we unboxed the monadic value by
matching it with the pattern `Some x`---whenever `u`
happened to be a box containing an integer `x`, this allowed us to
get our hands on that `x` and feed it to `f`.
For each new monadic type, this has to be worked out in an
useful way.
-So the "option/maybe monad" consists of the polymorphic `option` type, the
+So the "Option/Maybe monad" consists of the polymorphic `option` type, the
`unit`/return function, and the `bind` function.
`x`".
(Note that the above "do" notation comes from Haskell. We're mentioning it here
-because you're likely to see it when reading about monads. It won't work in
+because you're likely to see it when reading about monads. (See our page on [[Translating between OCaml Scheme and Haskell]].) It won't work in
OCaml. In fact, the `<-` symbol already means something different in OCaml,
having to do with mutable record fields. We'll be discussing mutation someday
soon.)
-As we proceed, we'll be seeing a variety of other monad systems. For example, another monad is the list monad. Here the monadic type is:
+As we proceed, we'll be seeing a variety of other monad systems. For example, another monad is the List monad. Here the monadic type is:
# type 'a list
# List.concat [[1]; [1;2]; [1;3]; [1;2;4]]
- : int list = [1; 1; 2; 1; 3; 1; 2; 4]
-So now we've seen two monads: the option/maybe monad, and the list monad. For any
+So now we've seen two monads: the Option/Maybe monad, and the List monad. For any
monadic system, there has to be a specification of the complex monad type,
which will be parameterized on some simpler type `'a`, and the `unit`/return
operation, and the `bind` operation. These will be different for different
* **Associativity: bind obeys a kind of associativity**. Like this:
- (u >>= f) >>= g == u >>= (fun x -> f x >>= g)
+ (u >>= f) >>= g == u >>= (fun x -> f x >>= g)
If you don't understand why the lambda form is necessary (the
"fun x -> ..." part), you need to look again at the type of `bind`.
- Some examples of associativity in the option monad (bear in
+ Wadler and others try to make this look nicer by phrasing it like this,
+ where U, V, and W are schematic for any expressions with the relevant monadic type:
+
+ (U >>= fun x -> V) >>= fun y -> W == U >>= fun x -> (V >>= fun y -> W)
+
+ Some examples of associativity in the Option monad (bear in
mind that in the Ocaml implementation of integer division, 2/3
evaluates to zero, throwing away the remainder):
# Some 3 >>= (fun x -> divide 2 x >>= divide 6);;
- : int option = None
-Of course, associativity must hold for *arbitrary* functions of
-type `'a -> 'b m`, where `m` is the monad type. It's easy to
-convince yourself that the `bind` operation for the option monad
-obeys associativity by dividing the inputs into cases: if `u`
-matches `None`, both computations will result in `None`; if
-`u` matches `Some x`, and `f x` evalutes to `None`, then both
-computations will again result in `None`; and if the value of
-`f x` matches `Some y`, then both computations will evaluate
-to `g y`.
+ Of course, associativity must hold for *arbitrary* functions of
+ type `'a -> 'b m`, where `m` is the monad type. It's easy to
+ convince yourself that the `bind` operation for the Option monad
+ obeys associativity by dividing the inputs into cases: if `u`
+ matches `None`, both computations will result in `None`; if
+ `u` matches `Some x`, and `f x` evalutes to `None`, then both
+ computations will again result in `None`; and if the value of
+ `f x` matches `Some y`, then both computations will evaluate
+ to `g y`.
* **Right identity: unit is a right identity for bind.** That is,
`u >>= unit == u` for all monad objects `u`. For instance,
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_topics/monads_in_category_theory).
-See also <http://www.haskell.org/haskellwiki/Monad_Laws>.
+
+See also:
+
+* [Haskell wikibook on Monad Laws](http://www.haskell.org/haskellwiki/Monad_Laws).
+* [Yet Another Haskell Tutorial on Monad Laws](http://en.wikibooks.org/wiki/Haskell/YAHT/Monads#Definition)
+* [Haskell wikibook on Understanding Monads](http://en.wikibooks.org/wiki/Haskell/Understanding_monads)
+* [Haskell wikibook on Advanced Monads](http://en.wikibooks.org/wiki/Haskell/Advanced_monads)
+* [Haskell wikibook on do-notation](http://en.wikibooks.org/wiki/Haskell/do_Notation)
+* [Yet Another Haskell Tutorial on do-notation](http://en.wikibooks.org/wiki/Haskell/YAHT/Monads#Do_Notation)
+
Here are some papers that introduced monads into functional programming:
# 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?
+`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>
`lift2 (+)` 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`!
+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.
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
+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]]
But first, we'll look at several linguistic applications for monads, based
on what's called the *Reader monad*.
-##[[Reader monad for Variable Binding]]##
+##[[Reader Monad for Variable Binding]]##
-##[[Reader monad for Intensionality]]##
+##[[Reader Monad for Intensionality]]##