module Monad:sig..end
Introduction
Monads are a popular concept in Haskell and controversial just about everywhere else on the planet! They have been thought of by some in the Ocaml community as a "design pattern" (see the documentation for BatMonad), and a nice way to abstract over resource manipulation. My favourite example in Ocaml is the lwt library.
But I find that, in Ocaml, "monads" are typically seen rather narrowly in
terms of a bind and return function. Personally, I think monads are bigger
than that. They are an abstraction, and the meaning of that abstraction
is to be found in libraries which give you general functions that apply to
all monads. To make the point concretely, if we aren't automatically
deriving a Monad.Monad.join function for all of our monads, then we've missed
something important.
In other words, I want to say that monads as an abstraction are defined by an abstract monad library. Such a library is the purpose of this module.
I recommend checking out the the types in this module. I find they say a lot about the meaning of the various functions.
A rambling note on terminology
There's some confusing terminology when it comes to monads, which I'll try to clarify for the purposes of the documentation.
Now I'm no category theorist, but if I were to try to get technical, I'd say that a monad is a three-tuple: a type-constructor, and two functions. So, for instance, the list monad can be defined by three things:
list which appears in type expressions such as 'a list;return;bind.Terminology now gets a bit hairy, because as pointed out by Mark Dominus, we need to talk about many different things in the context of monads, which leads to overloading and an (overused) use of the adjective "monadic."
We have our three tuple above, we have the type-constructor list, we have
types such as int list, and we have values such as [1;2;3] : int
list. In general, I shall reserve "monad" for the type-constructor
list, and I'll read values such as [1;2;3] as "the computation in the
list monad which returns 1, 2 or 3." I will also read values of type m
() as "the computation in the m monad which returns nothing."
I'm not convinced that "computation" is the best analogy for what monads
are about, and I worry that if this metaphor gets taken too seriously,
we might miss some interesting monads. For now, I'm just treating it
as a useful metaphor for writing this documentation.
Author(s): Phil Scott
module type Monoid =sig..end
module type BasePlus =sig..end
module type BaseLazyPlus =sig..end
module type Reader =sig..end
module type Writer =sig..end
module State:
module Error:
module type BaseCollectionM =sig..end
module type Stream =sig..end
module type StreamC =sig..end
module type Monad =sig..end
module type MonadPlus =sig..end
module type LazyPlus =sig..end
Monad.BasePlus.
module Make:
module MakePlus:
module MakeLazyPlus:
module LazyM:BatInterfaces.Monadwith type 'a m = 'a Lazy.t
module List:BasePluswith type 'a m = 'a list
module LazyListM:BaseLazyPluswith type 'a m = 'a LazyList.t
module Option:BasePluswith type 'a m = 'a option
module Continuation:
module MakeReader:
module MakeWriter:
module MakeStream:
module MakeStreamC:
Monad.BaseCollectionM.
module LazyT:
module ListT:
module OptionT:
module StateT:
module WriterT:
Monad.BaseCollectionM.unique behave in a sensible
way by regarding None as smaller than any Some. Each transformer provides
a function cmp_on with which the collection functions such as
BaseCollectionM.difference are implemented. We also provide the list
function for transformers.module CollectionOpt:
module CollectionWriter:functor (W:siginclude Monad.Writerval cmp :t -> t -> boolend) ->
module CollectionState: