Re: FW: RE [Haskell-cafe] Monad Description For Imperative Programmer

2007-08-03 Thread David Menendez
On 8/1/07, Jeff Polakow [EMAIL PROTECTED] wrote:
 But what about an actual object of type 'IO
   Int', say?
 
 I usually describe the type resulting from applying a monad a computation.

Same here. If m is a monad, then m a is a computation. (Of course,
computations are first-class values, like functions.) I've
occasionally called functions of type a - m b monadic functions,
but I suspect that's poor style.

I wonder how much of the confusion surrounding monads comes from the
fact that using them in Haskell involves higher-order functions, type
constructors, and type constructor classes.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


RE: FW: RE [Haskell-cafe] Monad Description For Imperative Programmer

2007-08-02 Thread Bayley, Alistair
 From: [EMAIL PROTECTED] 
 [mailto:[EMAIL PROTECTED] On Behalf Of peterv
 
 However, one thing which I find annoying is that a classic 
 pure function cannot evaluate an IO function unless you use 
 unsafePerformIO; one must promote (?demote) the pure 
 function into the IO monad.

That's just a property of the IO monad, rather than monads in general:
http://www.haskell.org/all_about_monads/html/laws.html#nowayout


 Any ways of promoting such a pure function into the monadic 
 one automatically? I tried playing with liftM, without succes.

This is where Claus plugs HaRe :-) (although liftM + friends is normally
what one uses). You might find this relevant:
http://www.cs.kent.ac.uk/projects/refactor-fp/catalogue/Monadification1.
html

Some people (but I'm not sure who) probably write most of their Haskell
code in a monadic style, so as to make conversion between various monads
less painful. It's still pure...

Alistair
*
Confidentiality Note: The information contained in this message,
and any attachments, may contain confidential and/or privileged
material. It is intended solely for the person(s) or entity to
which it is addressed. Any review, retransmission, dissemination,
or taking of any action in reliance upon this information by
persons or entities other than the intended recipient(s) is
prohibited. If you received this in error, please contact the
sender and delete the material from any computer.
*
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: FW: RE [Haskell-cafe] Monad Description For Imperative Programmer

2007-08-01 Thread Dan Piponi
On 8/1/07, Andrew Wagner [EMAIL PROTECTED] wrote:
 For me, I think the key to monads is to really
 understand 2 things about them:
 ...
 2.) Monads are about sequencing

Now I disagree on 2.

Monads are no more about sequencing than binary operators are about
sequencing. Sure, if you want to, you can define an operator like (*)
to be non-commutative, so that a*b is different to b*a, but that
doesn't really get to the essence of what a binary operator is. And in
everyday usage we use (*) to mean ordinary commutative multiplication
where there is no sense of sequencing.

The same holds for monads. If you want to use them for sequencing the
option is there, but there are plenty of commutative monads out there,
for which the order of operations doesn't matter, and the fact that
they are commutative doesn't make them any less monads. So while you
can use monads to sequence, I don't think sequencing gets to the
essence of what monads are.

I suspect I hold a minority view here... :-)
--
Dan
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: FW: RE [Haskell-cafe] Monad Description For Imperative Programmer

2007-08-01 Thread Andrew Wagner

 an IO monad is a delayed action that will be executed as soon as that action 
 is needed for further evaluation of the program.


I'm not sure I like this, as it seems to confuse the issue. An expert
should correct me if I'm wrong, but monads in and of themselves don't
depend on laziness. Rather, *everything* in haskell is lazy, unless
explicitly strict-ified.

As for the rest of your email, I don't necessarily disagree, but don't
find it particularly helpful either. Which may, of course, be a
personal thing. For me, I think the key to monads is to really
understand 2 things about them:
1.) They are simply type constructor classes
2.) Monads are about sequencing

For point 2, think about the two main things you have to define to
create an instance of a monad:
(=) :: m a - (a - m b) - m b

That is, you have two monadic actions, m a and m b, and bind says how
to take the result of the first and fit it into the second -- in
sequence!

() :: m a - m b - m b

Again, we have 2 monadic actions that we're composing, in sequence.
This time, we're just discarding the result of the first.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: FW: RE [Haskell-cafe] Monad Description For Imperative Programmer

2007-08-01 Thread Jeff Polakow
Hello,

 On 8/1/07, Andrew Wagner [EMAIL PROTECTED] wrote:
  For me, I think the key to monads is to really
  understand 2 things about them:
  ...
  2.) Monads are about sequencing
 
 Now I disagree on 2.
 
 Monads are no more about sequencing than binary operators are about
 sequencing. Sure, if you want to, you can define an operator like (*)
 to be non-commutative, so that a*b is different to b*a, but that
 doesn't really get to the essence of what a binary operator is. And in
 everyday usage we use (*) to mean ordinary commutative multiplication
 where there is no sense of sequencing.
 
 The same holds for monads. If you want to use them for sequencing the
 option is there, but there are plenty of commutative monads out there,
 for which the order of operations doesn't matter, and the fact that
 they are commutative doesn't make them any less monads. So while you
 can use monads to sequence, I don't think sequencing gets to the
 essence of what monads are.
 
 I suspect I hold a minority view here... :-)

You are entirely correct.

Data dependencies enforce/specify sequencing.

-Jeff

---

This e-mail may contain confidential and/or privileged information. If you 
are not the intended recipient (or have received this e-mail in error) 
please notify the sender immediately and destroy this e-mail. Any 
unauthorized copying, disclosure or distribution of the material in this 
e-mail is strictly forbidden.___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: FW: RE [Haskell-cafe] Monad Description For Imperative Programmer

2007-08-01 Thread Dan Weston
Here's my rant about the way monads are explained in Haskell tutorials 
(which are much too polluted with nuclear waste to be safely approached):


It is a big mistake to start with the IO monad. It pollutes and 
misdirects the understanding of what a monad is. The dreaded nuclear 
waste metaphor is actually a red herring, having nothing do do with a 
monad at all, merely the artifact of the absence of an exit function in 
the IO monad (which actually does exist and is called unsafePerformIO, 
but that is a secret. Shhh...), combined with Haskell's refusal to work 
for free.


Monads are required to have an extrance (reification/constructor 
function) called return. They are *not* required to have an exit 
(reflection/deconstructor function).


They *do* combine (bind) together like links in a chain, which is not a 
list but an equivalence class of trees, where the only thing that 
matters is the order of the leaves, so unlike a list you don't have to 
start at the tail and assemble one-by-one. [Actually, the compiler picks 
just one of these trees (the singly-linked list) but expects that all 
trees would evaluate the same.]


They *do* bind only with flavors of themselves (State a cannot bind to 
IO b, though a monad transformer can merge the two). The output type of 
one monad instance must match the input type of another monad 
reification function (e.g. return) that it wants to bind to.


In compensation for this tribalism, those snobby monads that want to 
clique off are out of luck: a monad cannot restrict what possible types 
can be used to construct a monad instance. That would be discrimination, 
and you must agree to accept all comers.


Simple, no? Apparently not...

Other things have nothing to do with monads per se gunk up the 
descriptions about monads:


One red herring (the nuclear waste metaphor) refers to the fact since 
monads may or may not have an escape-clause (called variously runXXX, 
evalXXX, unsafePerformXXX), and IO in particular does not. The presence 
or absence of this has *nothing* to do with monads (only with IO), 
participates in no monadic laws, and shouldn't even be in the chapter on 
Monads. Whether nuclear waste seeps in (as in a State monad) or stays 
out (IO monad) has nothing to do with their monadic property and is a 
special property of those particular classes.


Another even redder herring is the dreaded sequencing aspect. Monads do 
sequence *denotationally*, the way any nested closures sequence, which 
is exactly *backwards* from the naive understanding of sequencing: 
symbols defined to the left are in the *inner* scope, those to the right 
are in the *outer* scope. Perversely, when the symbols are evaluated, 
the rightmost monad is evaluated first. The leftmost monad in the 
program, the IO () passed in by main, is the *last* thing to be 
evaluated, not the first. The outermost monad (rightmost bound function) 
is in the driver seat, and is absolutely free to ignore the monad to its 
left (which in turn encloses monads to its left)! This includes of 
course the main input IO () monad.  Don't believe me?


Prelude const 3 (return Nuclear waste leaking... = print) + 5
8

Phew, no nuclear waste leaked after all. What a relief!

This sequencing then has nothing to do with *operational* sequencing. 
When the symbols are evaluated is the basic call-by-need data-dependent 
stuff of most Haskell symbols and again, has nothing to do with monads.


I learned about the IO monad first and I regret it bitterly. It cost me 
a years' worth of misunderstanding. I misapprehended that a monad had 
something to do with nuclear waste and never escaping the 
single-threadedness. I hope the new O'Reilly book doesn't make that 
mistake. Teach IO right away, but just don't call it a monad. IO is the 
exception, not the rule, in the menagerie of Haskell monads.


How does all this map to C++? A monad is a a class, with no useful 
interface for the end user, that looks roughly (i.e. I haven't tested 
it) like:


template class M, class T
class Monad
{
public:

  virtual ~Monad() {}

  // return
  Monad(T t) : t_(t) {}

  // bind operator (=), where
  // F :: MonadM,T - (T - MonadM,U) - MonadM,U
  virtual template class U MonadM,U
operator(typename U::F f) = 0;

private:
  T t_;
};

C++ programmers will immediately see past the syntactic kruft to notice that
1) the constructor arg is not a value but an unevaluated function 
object, that starts out unevaluated.

2) The result of m  f is a monad object, totally unevaluated.
3) There is no member function to do anything with the monad at all! As 
is, it is useless.


Derivers of this class will naturally want to add such functionality:

template class M, class T
class MyMonad : public MonadM,T
{
  // The parent class needs to know what type of monad
  // this can bind to
  typedef someUnaryFunctionObjectTypeReturningB F;

  // There is no input, just an output!
  // The input is via the constructor arg of the innermost monad
  B 

Re: FW: RE [Haskell-cafe] Monad Description For Imperative Programmer

2007-08-01 Thread Jeff Polakow
Hello,

 'Monad' is a type class.
 
 So what's 'IO'? Is the correct terminology 'instance' as in 'IO is an
 instance of Monad'. I consider 'IO' to be 'a monad' as that fits with
 mathematical terminology. 

I agree with this.

But what about an actual object of type 'IO
 Int', say? 

I usually describe the type resulting from applying a monad a computation. 
Then 'IO Int' would be something like an IO computation of an Int. This 
terminology also jibes well with, or rather comes from, Moggi's 
computational lambda calculus (one of the early papers showing uses of 
Monads to computer science).

-Jeff


---

This e-mail may contain confidential and/or privileged information. If you 
are not the intended recipient (or have received this e-mail in error) 
please notify the sender immediately and destroy this e-mail. Any 
unauthorized copying, disclosure or distribution of the material in this 
e-mail is strictly forbidden.___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: FW: RE [Haskell-cafe] Monad Description For Imperative Programmer

2007-08-01 Thread Claus Reinke

a Monad is a type constructor with two operations, implementing
a standard interface and following a few simple rules.

the Monad type class tells you the interface (what operations
you've got, and their types), the Monad laws tell you what all
types implementing that interface should have in common. 


the monadic interface gives you two operations, one to throw
things into a monad thing (return), and one to chain two monad 
things together (=). the chaining explicitly caters for information
flowing from the first to the second parameter of (=). 

the monad laws tell you two useful facts about monad things 
thrown together in that way: whatever it is the monad does, 
anything just thrown into it will take no part in that action,
and whichever way you use that chaining operation, the 
structure of chaining is irrelevant, only the ordering of chained

monad things matters.

there are usually other ways to create 'primitive' monadic things,
which can be combined into complex monadic structures using 
the operations from the Monad interface.


there is usually a way to interpret monadic structures built in
this way (a 'run' operation of some kind).

that's it, i think?-)

claus

   examples include:

   - i/o: primitive monadic things are basic i/o operations, 
   the 'run' operation is outside the language, applied to

   'Main.main', and interprets (abstract) IO monad structures
   sequentially, starting with the leftmost innermost i/o 
   operation in the structure and applying the second

   argument of (=) to the result of executing the first.

   - []: primitive monadic things are lists, the 'run' operation
   is the identity, ie, the lists are directly exposed as data
   structures, return creates a singleton list, (=) applies
   its second argument to each element of its first argument
   and concatenates the results (concatMap).

   - State: primitive monadic things are operations on a state
   type, returning a result and a state; return returns its 
   parameter, passing its input state unchanged, (=) applies 
   its first parameter to the input state, applies its second 
   parameter to the result value and result state of the first. 
   'run' is runState and applies a (possibly) complex monadic 
   thing to an input state, returning a result and a (modified) 
   state.


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: FW: RE [Haskell-cafe] Monad Description For Imperative Programmer

2007-08-01 Thread Dan Weston
I knew someone was going to catch me wandering into the deep end of the 
pool!


Having read large parts of your blog, I would never presume to tell you 
anything about Haskell or category theory, but what the hell...


 I mostly sympathise with your rant, but I think you need to be clearer
 about what exactly is concatenated. In general you can't concatenate
 Monads. What you *can* concatenate are Kleisli arrows (ie. things of
 type Monad m = a - m b). You can also apply Kleisli arrows to
 Monads, and that's what = does.

 I feel that talking about Monads without Kleisli arrows is like
 talking about category theory without arrows, or at least sets without
 functions. In each case, without the latter, the former is more or
 less useless.

OK, I'll be clearer. I did actually mean Kleisli arrows, though I 
disagree about your statement about concatenating monad instances and 
claims of useless:


Prelude print Hello  return 3
Hello
3

Granted,  is not as general as =, so combining one monad instance 
with another is not as general as with a Kleisli arrow: concatenating 
degenerates to simple sequencing.


Sequencing print statements is more rather than less useless to many 
people, but I see your point. Actually, you have made my point! :)


The forgetful action of Kleisli arrows acting on a monad (or conversely 
the free algebra of a monad as a subspace of Kleisli arrows) is to my 
understanding intimately connected with the specialness of the IO monad. 
It is the continuous nature of Haskell monads that gives non-IO monads 
value. So I guess my rant really was about Kleisli arrows not all being 
forgetful functors, used only for their sequencing effect. It just 
sounded too hard to pull that argument off without reinforcing the myth 
that you need to know category theory to have a rant about Haskell 
tutorials.


 Also, I'm having a terminological difficulty that maybe someone can 
help with:


 'Monad' is a type class.

Actually I thought it was a type class constructor. The monad Monad m = 
m a is continuous in its instance type a, which is important in 
establishing the relationship between = and . The Haskell type 'IO 
()' is a monad instance that is also isomorphic to the discrete trivial 
monad, but that is not a Haskell Monad capital-M.


I used the term instance because the type IO () is an instance of the 
typeclass IO, not for any more profound reason.


Forgive the display of wanton ignorance above. After all, isn't that 
what ranting is all about?


Dan Weston

Dan Piponi wrote:

On 8/1/07, Dan Weston [EMAIL PROTECTED] wrote:

The moral of the story is that monads are less than meets the eye. You
can create them and concatenate them


I mostly sympathise with your rant, but I think you need to be clearer
about what exactly is concatenated. In general you can't concatenate
Monads. What you *can* concatenate are Kleisli arrows (ie. things of
type Monad m = a - m b). You can also apply Kleisli arrows to
Monads, and that's what = does.

I feel that talking about Monads without Kleisli arrows is like
talking about category theory without arrows, or at least sets without
functions. In each case, without the latter, the former is more or
less useless.

Also, I'm having a terminological difficulty that maybe someone can help with:

'Monad' is a type class.

So what's 'IO'? Is the correct terminology 'instance' as in 'IO is an
instance of Monad'. I consider 'IO' to be 'a monad' as that fits with
mathematical terminology. But what about an actual object of type 'IO
Int', say? Some people have been loosely calling such an object 'a
monad'. That doesn't seem quite right. Maybe it's 'an instance of IO
Int', though that's stretching the word 'instance' to meaning two
different things. And if an object of type IO Int is in instance of IO
Int, is it reasonable to also call it an 'instance of IO', or even 'an
instance of Monad'? I'm sure there are proper words for all these
things if someone fills me in.
--
Dan
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe





___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe