Yet Another Monad Tutorial

Jeff Newbern jnewbern@nomaware.com
12 Aug 2003 19:13:58 +0100


Peter,

Thank you for criticism.  This is exactly the kind of feedback I need.

The overall message I have taken from your post is that I need to
be more precise to convey the correct information and avoid confusion
(or worse, misinformation).

I should have said that a function which performs a computation
in the I/O monad must have IO as the outermost constructor
in its return type.  I think that is more precise (and correct :-).

As for the later text concerning "application" of the top-level I/O
action, I will need to think for a while to see how I can word this
more clearly.  If you (or anyone else) have ideas, I'd like to hear
them.

Thanks again,
Jeff

On Tue, 2003-08-12 at 18:24, Peter G. Hancock wrote:
> >>>>> Jeff Newbern wrote (on Tue, 12 Aug 2003 at 17:20):
> (proposed revisions)
> 
>     > In the section "No Way Out":
>     > ----------
>     > The IO monad is a familiar example of a one-way monad in Haskell.
>     > Because you can't escape from the IO monad, it is impossible to write a
>     > function that does a computation in the IO monad but returns a
>     > non-monadic value. 
> 
> I wouldn't say that, as it is inaccurate.  Of course you can return a
> value of _some_ monadic type eg. (Maybe ...).
> 
>     > Not only are functions of the type IO a -> a
>     > impossible to create, 
> 
> You can quite easily write a function of type IO (IO a) -> IO a, which
> is a special case of that type. 
> 
>     > but any function whose result type does not
>     > contain the IO type constructor is guaranteed not to use the IO monad.
> 
> That's rather vague: what does it mean for a function to use a monad?
> 
>     > Other monads, such as List and Maybe, do allow values out of the monad.
>     > So it is possible to write non-monadic functions that internally do
>     > computations in those monads. The one-way nature of the IO monad also
>     > has consequences when combining monads, a topic that is discussed in
>     > part III.
>     > ----------
> 
> In summary, I've only a vague idea of what you are trying to say.  If you
> can't reformulate it more precisely, don't add the above stuff.
> 
>     > and a little farther down:
> 
>     > ----------
>     > Some people argue that using monads to introduce non-pure features into
>     > Haskell disqualifies it from claiming to be a pure functional language.
>     > This subtle question   not particularly relevant to the practical
>     > programmer   is revisited in the context of the I/O monad later in the
>     > tutorial.
>     > ----------
> 
> That's fair enough.  I don't think the question is so much subtle as
> religious, as we might expect from the terminology of "purity". 
> 
>     > Later, in the section on the I/O monad:
>     > ----------
>     > In Haskell, the top-level main function must have type IO (), so that
>     > programs are typically structured at the top level as an
>     > imperative-style sequence of I/O actions and calls to functional-style
>     > code. Revisiting the debate about the purity of Haskell (in a functional
>     > sense), it is important to note that the IO monad only simulates
>     > imperative-style I/O. 
> 
> That (about simulation) seems weak.  A simulation isn't a vague syntactic 
> resemblance.
> 
>     > The functions exported from the IO module do not
>     > perform I/O themselves. They return I/O actions, which describe an I/O
>     > operation to be performed. The I/O actions are combined within the IO
>     > monad (in a purely functional manner) to create more complex I/O
>     > actions, resulting in the final I/O action that is the main value of the
>     > program. The result of the Haskell compiler is an executable function
>     > incorporating the main I/O action. Executing the program "applies" this
>     > ultimate I/O action to the outside world to produce a new state of the
>     > world. 
> 
> That seems to me the wrong thing to say.  There is no application.  Whether
> or not the word is put in quotes, it is something involving a function
> and an argument.  An IO action is not a function.
> 
>     > This occurs only once per execution of the program, and since the
>     > state of the world changes for each execution, the issue of purity is
>     > neatly side-stepped.
>     > ----------
> 
> By "the program", I think you mean the IO action.  I think it is right to
> speak of the action as something that is executed.  Execution may involve
> (side-effect free) calculation; but execution is something essentially 
> different from calculation, not an impure form of it.
> 
> 
> I'm sorry to sound negative -- it's just that you invited criticism.
> Your pages seem generally of a very high quality to me.  Sorry not
> to be more constructive too. 
> 
> Peter Hancock
-- 
Jeff Newbern <jnewbern@nomaware.com>
Nomaware, Inc.