I've been comparing the definition of the Clojure's state monad --
state-m in clojure.contrib.monads -- to definitions I've found
elsewhere, and there's a facet of the Clojure definition that's
puzzling: Why do monadic functions in state-m only accept one argument
(a "basic value") and return a monadic value (a function accepting a
state), as opposed to accepting both the "basic value" and a state?

Looking at the definitions for the state monad in Haskell, it seems
ambiguous as to whether the monadic functions accept one or two values,
but then functions in Haskell can all be curried, so it's hard to tell.

The paper "Monads for functional programming"¹ by Philip Wadler shows
the following definition of the bind operator on page 9:

  m * k = \X.let (a, y) = m x in
             let (b, z) = k a y in
             (b, z)

Note the application of function "k" is shown as

  k a y

where "a" is the basic value resulting from "m" and "y" is the state as
updated last by "m". This definition suggests that function "k" doesn't
make much sense without these two arguments supplied. Again, though,
this is Haskell, so supplying multiple arguments at once doesn't mean
much.

In the Haskell tutorial's article "The State monad"², the definition
looks more like Clojure's:

  (State x) >>= f =
    State $ \s -> let (v,s') = x s in runState (f v) s'

There we see monadic function "f" applied to basic value "v", and then
the result applied to the pending state "s'".

Clojure's definition is as follows:

  (fn m-bind-state [mv f]
    (fn [s]
      (let [[v ss] (mv s)]
        ((f v) ss))))

There, similarly, monadic function "f" is applied first to basic value
"v", and then the result applied to the pending state "ss".


My question: What's the benefit of having the monadic function accept
only the basic value, deferring consideration of the state, as opposed
to having it accept both the basic value and the pending state together?

As I write this, I realize that following Clojure's definition ensures
that "monadic functions return monadic values", and here a monadic value
is a function that accepts a state.

What's been difficult, though, is actually writing monadic functions for
use in the state monad. It feels wrong to define a function whose
outcome depends both on the input basic value and the input state, but
to have to "cut the function in half", receiving the two values as
separate steps.

Sometimes the function depends only upon the input value, in which case
the `m-result' is sufficient to provide the resulting monadic
value. Sometimes the function depends on both the input value and the
state, in which case we have to just close over the input value and
defer its consideration until we receive the state later.

What would be lost by defining Clojure bind operator like this:

  (fn m-bind-state [mv f]
    (fn [s]
      (let [[v ss] (mv s)]
        (f v ss))))

Is there more to it than, "Monadic functions must return monadic
values"?

Any clarifying advice would be welcome.


Footnotes: 
¹ http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf
² http://www.haskell.org/all_about_monads/html/statemonad.html

-- 
Steven E. Harris

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to