Re: [Haskell-cafe] Explaining monads

2007-08-16 Thread Kim-Ee Yeoh


Paul Hudak wrote:
> 
> [I]n the one-of-many ways that I view monads, a monad is just a high-order
> function that abstracts away function composition.  In particular, if I
> have an action f, and an action g, I can think of them as recipes, because
> I can combine them via f >>= g.  It's only after I combine all of my
> actions together that I apply the result to my input (via "run").
> 
> Well, that's just like function composition.  In particular, if I have a
> function f, and a function g, I can think of them as recipes, because I
> can combine them via f . g.
> 

First a nitpick:

At the beginning of the thread I had pointed out how co/monadic 
co/bind generalizes function /application/, i.e. flip ($).

Generalized function /composition/ on the other hand has a different 
type. For instance, in the case of monads it's
 
\begin{code}

(<.>) :: Monad m => (a -> m b) -> (c -> m a) -> (c -> m b)
(<.>) f g c = (g c) >>= f

\end{code}

Function (<.>) is flip (>>>) in the instance of Monad m => Arrow
(Kleisli m). (For a moment there I couldn't find it in the haskell
libs. Would be nice if Hoogle could read instances such as these. I
must not be using Hoogle right, I couldn't even locate (>>=) by
type signature.)

Returning to the main point, like you and Dan P, I also have my
reservations explaining a monadified value as a recipe, although
for arguably different reasons. It's too chef-centric for me, to
continue with the original analogy. I have an allergic reaction to
"run" functions, at least what they connote. I claim that in
genuinely monadic programming, you never think about "run". Code
that's genuinely monadic works for all monads. Code like that is
what you want to write.

Or put another way, you just program like before except lifting
stuff into an arbitrary monad. You then write different monads
to retrofit the various add-on computations you want performed.

I thought this is well-known for over 15 years?

-- 
View this message in context: 
http://www.nabble.com/Explaining-monads-tf4244948.html#a12185261
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

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


Re: [Haskell-cafe] Explaining monads

2007-08-15 Thread Paul Hudak
I've seen the analogy with "recipes" used before, but I think that you 
need to be careful when you try to distinguish the analogy to monads 
from the analogy to functions.  The reason is that, in the one-of-many 
ways that I view monads, a monad is just a high-order /function /that 
abstracts away function composition.  In particular, if I have an action 
f, and an action g, I can think of them as recipes, because I can 
combine them via f >>= g.  It's only after I combine all of my actions 
together that I apply the result to my input (via "run").


Well, that's just like function composition.  In particular, if I have a 
function f, and a function g, I can think of them as recipes, because I 
can combine them via f . g.  It's only after I combine all of my 
functions together that I apply the result to my input.


   -Paul


Sebastian Sylvan wrote:

On 14/08/07, Dan Piponi <[EMAIL PROTECTED]> wrote:
  

On 8/14/07, Sebastian Sylvan <[EMAIL PROTECTED]> wrote:


Well that's easy, don't use the recipe analogy to explain code, use it
for monadic values exclusively, and you avoid the confusion entirely!

I don't think it's that complicated.
  

It certainly is complicated. I think I have a good grasp of monads to
the point where I can tease novel monads (and comonads) out from
algorithms that people previously didn't see as monadic. And yet I
still don't understand what you are saying (except with respect to one
specific monad, IO, where I can interpret 'action' as meaning an I/O
operation).



Monads have a monadic type. They
represent an abstract form of an "action", which can be viewed as an
analogy to real-world cooking recipes.
  

All functions can be viewed as recipes. (+) is a recipe. Give me some
ingredients (two numbers) and I'll use (+) to give you back their sum.



No, (+) is a function, not a "recipe". Again, you're introducing
confusion because you use the same analogy for two *different* things.
Use it for one of the things and you don't have that problem.
I want to use "recipe" to mean "an abstraction for an action". It
could litterally be a text string containing the C code required to do
a particular IO action, for example. (+) isn't an abstraction in the
same sense, it *is* the "action" itself. (+) is the actual value of
the function that will add two numbers together. A monadic value is an
abstract recipe that you can't actually use directly (you can only
combine them, and if you're lucky you can "perform" them once you're
done combining them, e.g. ST, but not IO).


  

As long as you don't
deliberately confuse things by using the same analogy for two
different things I don't see where confusion would set in.
  

If I was one of your students and you said that monads are recipes I
would immediately ask you where the monads are in my factorial program
regardless of whether you had introduced one or two different
analogies for recipes.



Why would you? I really don't see where you would get that idea? If I
tell you that a function returns "a fruit", would you ask where the
fruit in your factorial program is? Probably not. Why would you go off
and take an analogy for monads and apply it to something completely
different and still think the analogy holds?
A function is *not* a recipe in this analogy, it's just a function
(which you hopefully should've covered by the time you get to monads.
Monadic values, and *only* monadic values (not functions!) are to be
viewed as analogous to real world cooking recipes in this analogy.
Functions shouldn't. If you start mixing things together it will get
confused, so just don't!

I don't think this is very difficult to understand, so if you still
don't get it, I think you're just going to have to read it again
because I can't explain it any better, and in my experience, newbies
tend to understand this analogy within seconds (maybe that's the
problem, you're not a newbie)...
  
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Explaining monads

2007-08-15 Thread Andy Gimblett
On Tue, Aug 14, 2007 at 05:53:05PM -0700, Michael Vanier wrote:
>
> For what it's worth, the nature of Haskell is such that you do (at
> least currently) have to spend a lot of time reading research papers
> to understand what's going on.  Maybe that will change sometime, but
> probably not soon.  This ties in to the open-endedness of Haskell; I
> sometimes think that really understanding all of Haskell is like
> really understanding all of mathematics.  This is frustrating, but
> it's also what makes the language so rewarding.  I guess what I'm
> saying is: get used to it, it's not so bad.

At AngloHaskell, one of Phillipa's slides referred to Haskell as a
"programming language theory gateway drug" - and was clearly of the
opinion that this was A Good Thing.

-- 
Andy Gimblett
Computer Science Department
University of Wales Swansea
http://www.cs.swan.ac.uk/~csandy/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Michael Vanier
For what it's worth, the nature of Haskell is such that you do (at least currently) have to spend a 
lot of time reading research papers to understand what's going on.  Maybe that will change sometime, 
but probably not soon.  This ties in to the open-endedness of Haskell; I sometimes think that really 
understanding all of Haskell is like really understanding all of mathematics.  This is frustrating, 
but it's also what makes the language so rewarding.  I guess what I'm saying is: get used to it, 
it's not so bad.


Mike

Derek Elkins wrote:

On Tue, 2007-08-14 at 12:40 -0500, Lanny Ripple wrote:

Derek Elkins wrote:

What people need to do is stop reading two page blog posts by someone
who's "just got" monads and read the well-written peer-reviewed papers
I have taught many people to program in group settings and 
individually in my career.  I have referred them to many 
tutorials.  I have used many examples from tutorials I thought 
were useful.  I can't recall a single time I've ever turned to a 
beginner and said, "And you really should brush up on the 
peer-reviewed papers to learn this part."


How about a book?  You've never recommended a book?  But even so, where
did I say tutorial?  The -are- good monad tutorials, they are just
horribly out-weighed by bad ones.  Further, having a tutorial as
supplement to person-to-person education is totally different from
trying to learn purely from tutorials.  Also, what is wrong with papers
or recommending them?  Finally, how often have you been part of a
community where the primary mode of documentation is a research paper...


by the people who clearly know what they are talking about.  Luckily,
for monads applied to Haskell we have Wadler, a witty, enjoyable and
clear writer/speaker.  All of Wadler's monad "introductions" are
readable by anyone with a basic grasp of Haskell.  You certainly don't
need to be even remotely an academic to understand them.  I'm willing to
bet that many people who say they don't understand monads and have read
"every tutorial about them" haven't read -any- of Wadler's papers.



I'm confused.  Are you praising Wadler or bashing the tutorials 
(or both)?  *I* was carping about the tutorials (and even 
mentioned that Wadler was my breakthrough) so I suspect we are in 
violent agreement.


I'm praising Wadler and bashing the good majority of monad tutorials,
but not all of them.  Mostly I'm pointing out an unreasonable aversion
to reading papers, as if a paper couldn't possibly be understandable.

___
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


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Derek Elkins
On Tue, 2007-08-14 at 12:40 -0500, Lanny Ripple wrote:
> Derek Elkins wrote:
> > What people need to do is stop reading two page blog posts by someone
> > who's "just got" monads and read the well-written peer-reviewed papers
> 
> I have taught many people to program in group settings and 
> individually in my career.  I have referred them to many 
> tutorials.  I have used many examples from tutorials I thought 
> were useful.  I can't recall a single time I've ever turned to a 
> beginner and said, "And you really should brush up on the 
> peer-reviewed papers to learn this part."

How about a book?  You've never recommended a book?  But even so, where
did I say tutorial?  The -are- good monad tutorials, they are just
horribly out-weighed by bad ones.  Further, having a tutorial as
supplement to person-to-person education is totally different from
trying to learn purely from tutorials.  Also, what is wrong with papers
or recommending them?  Finally, how often have you been part of a
community where the primary mode of documentation is a research paper...

> 
> > by the people who clearly know what they are talking about.  Luckily,
> > for monads applied to Haskell we have Wadler, a witty, enjoyable and
> > clear writer/speaker.  All of Wadler's monad "introductions" are
> > readable by anyone with a basic grasp of Haskell.  You certainly don't
> > need to be even remotely an academic to understand them.  I'm willing to
> > bet that many people who say they don't understand monads and have read
> > "every tutorial about them" haven't read -any- of Wadler's papers.


> I'm confused.  Are you praising Wadler or bashing the tutorials 
> (or both)?  *I* was carping about the tutorials (and even 
> mentioned that Wadler was my breakthrough) so I suspect we are in 
> violent agreement.

I'm praising Wadler and bashing the good majority of monad tutorials,
but not all of them.  Mostly I'm pointing out an unreasonable aversion
to reading papers, as if a paper couldn't possibly be understandable.

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


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Sebastian Sylvan
On 14/08/07, Seth Gordon <[EMAIL PROTECTED]> wrote:
> Sebastian Sylvan wrote:
> > On 14/08/07, Dan Piponi <[EMAIL PROTECTED]> wrote:
> >> If I was one of your students and you said that monads are recipes I
> >> would immediately ask you where the monads are in my factorial program
> >> regardless of whether you had introduced one or two different
> >> analogies for recipes.
> >
> > Why would you? I really don't see where you would get that idea? If I
> > tell you that a function returns "a fruit", would you ask where the
> > fruit in your factorial program is? Probably not. Why would you go off
> > and take an analogy for monads and apply it to something completely
> > different and still think the analogy holds?
> > A function is *not* a recipe in this analogy, it's just a function
> > (which you hopefully should've covered by the time you get to monads.
> > Monadic values, and *only* monadic values (not functions!) are to be
> > viewed as analogous to real world cooking recipes in this analogy.
> > Functions shouldn't. If you start mixing things together it will get
> > confused, so just don't!
>
> As a mostly-newbie who is working on his own monad tutorial
> (bwah-hah-hah), I share Dan's confusion about your analogy.
>
> Teacher: "Monads are like recipes."
>
> Student: "Aren't functions like recipes, too?"
>
> Teacher: "Well, yes, but we're talking about monads now, not functions."
>

Teacher: No, functions are like chefs. They do things to their input.
Monads are like recipes, they don't *do* anything at all, they just
represent an action, they need chefs to interpret them.

-- 
Sebastian Sylvan
+44(0)7857-300802
UIN: 44640862
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Seth Gordon

Sebastian Sylvan wrote:

On 14/08/07, Dan Piponi <[EMAIL PROTECTED]> wrote:

If I was one of your students and you said that monads are recipes I
would immediately ask you where the monads are in my factorial program
regardless of whether you had introduced one or two different
analogies for recipes.


Why would you? I really don't see where you would get that idea? If I
tell you that a function returns "a fruit", would you ask where the
fruit in your factorial program is? Probably not. Why would you go off
and take an analogy for monads and apply it to something completely
different and still think the analogy holds?
A function is *not* a recipe in this analogy, it's just a function
(which you hopefully should've covered by the time you get to monads.
Monadic values, and *only* monadic values (not functions!) are to be
viewed as analogous to real world cooking recipes in this analogy.
Functions shouldn't. If you start mixing things together it will get
confused, so just don't!


As a mostly-newbie who is working on his own monad tutorial 
(bwah-hah-hah), I share Dan's confusion about your analogy.


Teacher: "Monads are like recipes."

Student: "Aren't functions like recipes, too?"

Teacher: "Well, yes, but we're talking about monads now, not functions."

That response doesn't help the student, because the student already 
knows about functions, and would probably understand monads a lot better 
if he or she knew how monads are *different from* functions. 
(Especially since, umm, isn't the ((->) a) data type a monad?)

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


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Sebastian Sylvan
On 14/08/07, Malte Milatz <[EMAIL PROTECTED]> wrote:
> Dan Piponi, Tue, 14 Aug 2007 11:52:16 -0700:
> > All functions can be viewed as recipes. (+) is a recipe. Give me some
> > ingredients (two numbers) and I'll use (+) to give you back their sum.
>
> (+) is not a recipe, it is a chef. On the other hand,
> (return 5 :: State Integer) is a recipe. You need a
> chef, namely runState, to get your meal.
>
> Oh my, imagery can be so crazy.

Thank you! That does make sense.

-- 
Sebastian Sylvan
+44(0)7857-300802
UIN: 44640862
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Malte Milatz
Dan Piponi, Tue, 14 Aug 2007 11:52:16 -0700:
> All functions can be viewed as recipes. (+) is a recipe. Give me some
> ingredients (two numbers) and I'll use (+) to give you back their sum.

(+) is not a recipe, it is a chef. On the other hand, 
(return 5 :: State Integer) is a recipe. You need a
chef, namely runState, to get your meal.

Oh my, imagery can be so crazy.

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


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Arie Peterson

Dan Piponi wrote:

| On 8/14/07, Lennart Augustsson <[EMAIL PROTECTED]> wrote:
| > You don't normally call x::Int a computation of an Int because there's
| > nothing that distinguishes the value of the x from what it was before
| > you computed it.
|
| Can you spell out exactly what you mean by this?

Let's take a formal viewpoint: when writing a haskell program, you specify
what properties your values must satisfy. So 'x = 6' means that I want 'x'
to equal the value 6. To make solution of these equations tractable, we
have agreed that we treat them as (recursive) definitions of the LHS.

Now, the compiler may actually treat 'x = 6' as a specification of a
computation. From this formal point of view, however, that is an
implementation detail, and we don't need to speak about 'computations'.

Does this help at all?


| When someone uses the phrase "something else" it implies that we are
| talking about two things, a "something" and a disjoint "something
| else". For example, if x = [1,2,3] what is the "something" and what is
| the "something else"? What was the x "before [I] computed it" and how
| does it differ from its "value"?
|
|| This is just the terminology people use, not an absolute truth, so
|| you're free to think it's wrong. :)
|
| For something like this I prefer to think in terms of "useful" and
| "not useful". If you find the term "computation" useful, I might find
| it useful too. So I'm jealous as I can't figure out how to use it. :-)
| I'm not looking for a formal definition or anything like that. But I
| would like a reliable way to distinguish between things that are
| computations and things that are not.

Well, it depends on the context really, and on how hard you squint. Sorry
to disappoint you :-) (friendly apologetic smile, not an evil laugh).

Instead of [1,2,3], let me underhandly take the list [False,True]. Nothing
'computational' about it, right? Just a basic list, with some boolean
entries.

But behold! In the context of the 'power set' function from the other thread:

> power = filterM (const [False,True])

, this innocuous list suddenly reveals its monadic/computational
character. In this context, you may interpret [False,True] as a
'multi-valued computation of a boolean', which yields both False and True.
'const [False,True]' is a monadic predicate, which yields both False and
True on any element. filterM then applies this predicate to all elements
of a list, sequencing the computational/multi-valued aspects.


Greetings,

Arie

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


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Sebastian Sylvan
On 14/08/07, Dan Piponi <[EMAIL PROTECTED]> wrote:
> On 8/14/07, Sebastian Sylvan <[EMAIL PROTECTED]> wrote:
> > Well that's easy, don't use the recipe analogy to explain code, use it
> > for monadic values exclusively, and you avoid the confusion entirely!
> >
> > I don't think it's that complicated.
>
> It certainly is complicated. I think I have a good grasp of monads to
> the point where I can tease novel monads (and comonads) out from
> algorithms that people previously didn't see as monadic. And yet I
> still don't understand what you are saying (except with respect to one
> specific monad, IO, where I can interpret 'action' as meaning an I/O
> operation).
>
> > Monads have a monadic type. They
> > represent an abstract form of an "action", which can be viewed as an
> > analogy to real-world cooking recipes.
>
> All functions can be viewed as recipes. (+) is a recipe. Give me some
> ingredients (two numbers) and I'll use (+) to give you back their sum.

No, (+) is a function, not a "recipe". Again, you're introducing
confusion because you use the same analogy for two *different* things.
Use it for one of the things and you don't have that problem.
I want to use "recipe" to mean "an abstraction for an action". It
could litterally be a text string containing the C code required to do
a particular IO action, for example. (+) isn't an abstraction in the
same sense, it *is* the "action" itself. (+) is the actual value of
the function that will add two numbers together. A monadic value is an
abstract recipe that you can't actually use directly (you can only
combine them, and if you're lucky you can "perform" them once you're
done combining them, e.g. ST, but not IO).


>
> > As long as you don't
> > deliberately confuse things by using the same analogy for two
> > different things I don't see where confusion would set in.
>
> If I was one of your students and you said that monads are recipes I
> would immediately ask you where the monads are in my factorial program
> regardless of whether you had introduced one or two different
> analogies for recipes.

Why would you? I really don't see where you would get that idea? If I
tell you that a function returns "a fruit", would you ask where the
fruit in your factorial program is? Probably not. Why would you go off
and take an analogy for monads and apply it to something completely
different and still think the analogy holds?
A function is *not* a recipe in this analogy, it's just a function
(which you hopefully should've covered by the time you get to monads.
Monadic values, and *only* monadic values (not functions!) are to be
viewed as analogous to real world cooking recipes in this analogy.
Functions shouldn't. If you start mixing things together it will get
confused, so just don't!

I don't think this is very difficult to understand, so if you still
don't get it, I think you're just going to have to read it again
because I can't explain it any better, and in my experience, newbies
tend to understand this analogy within seconds (maybe that's the
problem, you're not a newbie)...

-- 
Sebastian Sylvan
+44(0)7857-300802
UIN: 44640862
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Jeff Polakow
Hello,

> On 14/08/07, Jeff Polakow <[EMAIL PROTECTED]> wrote:
> Of course, the type [Int] denotes a value which is a list of Ints; 
> additionally [Int] can be viewed as a value representing the 
> nondeterministic computation of a single Int. Generally, the type 
> Monad m => m Int can be viewed as a value representing the 
> computation of an Int. 
> 
> 
> But thats not really right. What exactly m Int does /depends/ on m. 
> It might represent 0 or more computations
> of Int, or computations of Int carrying some extra stuff around, or 
> complex control logic about what the computation does 
> when.
> 
Perhaps the confusion is in the word computation. I'm using the word in an 
abstract sense. I do not mean the actual execution of Haskell code to 
produce a value. Thus, under this intuition:

The type Int represents a value which denotes an Int. The type m Int 
denotes a value which is a single computation (for an unspecified notion 
of computation) of an Int. A specific computation of an Int might result 
in several, or zero, actual Ints (the list monad); a String or an Int (the 
Either String monad); the constant () (the trivial monad); ...

The type Monad m => m Int cannot represent multiple computations of an 
Int. The type Monad m => [m Int] represents multiple computations of an 
Int (of course, any container type can be used in place of list).

-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: [Haskell-cafe] Explaining monads

2007-08-14 Thread Dan Piponi
On 8/14/07, Sebastian Sylvan <[EMAIL PROTECTED]> wrote:
> Well that's easy, don't use the recipe analogy to explain code, use it
> for monadic values exclusively, and you avoid the confusion entirely!
>
> I don't think it's that complicated.

It certainly is complicated. I think I have a good grasp of monads to
the point where I can tease novel monads (and comonads) out from
algorithms that people previously didn't see as monadic. And yet I
still don't understand what you are saying (except with respect to one
specific monad, IO, where I can interpret 'action' as meaning an I/O
operation).

> Monads have a monadic type. They
> represent an abstract form of an "action", which can be viewed as an
> analogy to real-world cooking recipes.

All functions can be viewed as recipes. (+) is a recipe. Give me some
ingredients (two numbers) and I'll use (+) to give you back their sum.

> As long as you don't
> deliberately confuse things by using the same analogy for two
> different things I don't see where confusion would set in.

If I was one of your students and you said that monads are recipes I
would immediately ask you where the monads are in my factorial program
regardless of whether you had introduced one or two different
analogies for recipes. There are two sides to every analogy. If you
have an analogy between A and B then you can use knowledge about A to
understand B. But conversely, if you can't set up the same analogy
between A and B then that tells you something useful about B also. As
far as I can see, your description of a monad fits every computer
program I have ever written, and as a result I don't see what it is
that makes monads special. And monads are special.
--
Dan
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Sebastian Sylvan
On 14/08/07, Dan Piponi <[EMAIL PROTECTED]> wrote:
> On 8/14/07, Sebastian Sylvan <[EMAIL PROTECTED]> wrote:
> > On 14/08/07, Dan Piponi <[EMAIL PROTECTED]> wrote:
> > > Where do monads come in?
> >
> > Well I would try to distinguish between code that we write to compute
> > values, and values which represent monadic actions when coming up with
> > analogies.
>
> How would you make that distinction?

How can you *not* make a distinction? If you view source code as
recipes, that's fine, but the *code* doesn't even exist in the
program! You can't pass *code* around (unless you do it as String).
Clearly there's a gulf of difference between the source code ASCII
string that represent the factorial function, and a first class value
that represents an action *in* the language.


> At this point I can imagine
> students immediately thinking that my factorial program is a recipe
> and wondering why it doesn't involve monads.

Well that's easy, don't use the recipe analogy to explain code, use it
for monadic values exclusively, and you avoid the confusion entirely!

I don't think it's that complicated. Monads have a monadic type. They
represent an abstract form of an "action", which can be viewed as an
analogy to real-world cooking recipes. As long as you don't
deliberately confuse things by using the same analogy for two
different things I don't see where confusion would set in.


-- 
Sebastian Sylvan
+44(0)7857-300802
UIN: 44640862
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Dan Piponi
On 8/14/07, Sebastian Sylvan <[EMAIL PROTECTED]> wrote:
> On 14/08/07, Dan Piponi <[EMAIL PROTECTED]> wrote:
> > Where do monads come in?
>
> Well I would try to distinguish between code that we write to compute
> values, and values which represent monadic actions when coming up with
> analogies.

How would you make that distinction? At this point I can imagine
students immediately thinking that my factorial program is a recipe
and wondering why it doesn't involve monads. Either you distinguish
between these things in a circular way using monads (no use when
teaching monads in the first place) or you have some a priori
distinction that you point out to students.
--
Dan
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Dan Piponi
On 8/14/07, Lennart Augustsson <[EMAIL PROTECTED]> wrote:
> You don't normally call x::Int a computation of an Int because there's
> nothing that distinguishes the value of the x from what it was before you
> computed it.

Can you spell out exactly what you mean by this?

> So I prefer to regard x as a value (in a domain, of course).
> But for x :: (Monad m) => m Int there is something else happening

When someone uses the phrase "something else" it implies that we are
talking about two things, a "something" and a disjoint "something
else". For example, if x = [1,2,3] what is the "something" and what is
the "something else"? What was the x "before [I] computed it" and how
does it differ from its "value"?

> This is just the terminology people use, not an absolute truth, so you're
> free to think it's wrong. :)

For something like this I prefer to think in terms of "useful" and
"not useful". If you find the term "computation" useful, I might find
it useful too. So I'm jealous as I can't figure out how to use it. :-)
I'm not looking for a formal definition or anything like that. But I
would like a reliable way to distinguish between things that are
computations and things that are not.
--
Dan
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Brian Brunswick
On 14/08/07, Jeff Polakow <[EMAIL PROTECTED]> wrote:
>
> Of course, the type [Int] denotes a value which is a list of Ints;
> additionally [Int] can be viewed as a value representing the
> nondeterministic computation of a single Int. Generally, the type Monad m =>
> m Int can be viewed as a value representing the computation of an Int.



But thats not really right. What exactly m Int does /depends/ on m. It might
represent 0 or more computations
of Int, or computations of Int carrying some extra stuff around, or complex
control logic about what the computation does
when.

All that is really given, is that we can feed another 'Int->m a' thingy to
it using bind, and get back an m a, and the
thingy we fed in might even be used zero or more times while doing it.

These 'thingy's are called Kleisli Arrows, by the way.

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


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Jeff Polakow
Hello,

> On 8/14/07, Jeff Polakow <[EMAIL PROTECTED]> wrote:
> > One general intuition about monads is that they represent computations
> > rather than simple (already computed) values:
> 
> > x :: Int   -- x is an Int
> > x :: Monad m => m Int  -- x is a computation of an Int
> 
> What's a "computation"? It seems to me that in a lazy language, x::Int
> represents a computation of an int, not an "already computed" value.
>
This intuition for monads as "computations" is independent of operational 
semantics.

> x::[Int] is a computation that returns multiple values. x::(Int,Int)
> is a computation that returns a pair of values. x::() is a computation
> that returns nothing. x::Map a b is a computation that gives a way to
> associate values of type a with values of type b. Some of these are
> monads, some are not. What's the difference between them? Why are you
> calling certain values "computations"?
>
Of course, the type [Int] denotes a value which is a list of Ints; 
additionally [Int] can be viewed as a value representing the 
nondeterministic computation of a single Int. Generally, the type Monad m 
=> m Int can be viewed as a value representing the computation of an Int. 
However, I do not mean to imply that everything which can be viewed as a 
computation of something is a monad. 

In any case, this is only meant to be a general (i.e. high-level) 
intuition. BTW, this intuition was, more or less, the one used by Moggi 
when describing how monads can be used to describe denotational models for 
languages.

-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: [Haskell-cafe] Explaining monads

2007-08-14 Thread Lanny Ripple


Derek Elkins wrote:

What people need to do is stop reading two page blog posts by someone
who's "just got" monads and read the well-written peer-reviewed papers


I have taught many people to program in group settings and 
individually in my career.  I have referred them to many 
tutorials.  I have used many examples from tutorials I thought 
were useful.  I can't recall a single time I've ever turned to a 
beginner and said, "And you really should brush up on the 
peer-reviewed papers to learn this part."



by the people who clearly know what they are talking about.  Luckily,
for monads applied to Haskell we have Wadler, a witty, enjoyable and
clear writer/speaker.  All of Wadler's monad "introductions" are
readable by anyone with a basic grasp of Haskell.  You certainly don't
need to be even remotely an academic to understand them.  I'm willing to
bet that many people who say they don't understand monads and have read
"every tutorial about them" haven't read -any- of Wadler's papers.


I'm confused.  Are you praising Wadler or bashing the tutorials 
(or both)?  *I* was carping about the tutorials (and even 
mentioned that Wadler was my breakthrough) so I suspect we are in 
violent agreement.


  -ljr

--
Lanny Ripple <[EMAIL PROTECTED]>
ScmDB / Cisco Systems, Inc.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Lennart Augustsson
You don't normally call x::Int a computation of an Int because there's
nothing that distinguishes the value of the x from what it was before you
computed it.  So I prefer to regard x as a value (in a domain, of course).
But for x :: (Monad m) => m Int there is something else happening, so the
word computation makes sense.
This is just the terminology people use, not an absolute truth, so you're
free to think it's wrong. :)
BTW, if you regard non-termination as an effect then even x :: Int is a
computation.

  -- Lennart

On 8/14/07, Dan Piponi <[EMAIL PROTECTED]> wrote:
>
> On 8/14/07, Jeff Polakow <[EMAIL PROTECTED]> wrote:
> > One general intuition about monads is that they represent computations
> > rather than simple (already computed) values:
>
> > x :: Int   -- x is an Int
> > x :: Monad m => m Int  -- x is a computation of an Int
>
> What's a "computation"? It seems to me that in a lazy language, x::Int
> represents a computation of an int, not an "already computed" value.
> x::[Int] is a computation that returns multiple values. x::(Int,Int)
> is a computation that returns a pair of values. x::() is a computation
> that returns nothing. x::Map a b is a computation that gives a way to
> associate values of type a with values of type b. Some of these are
> monads, some are not. What's the difference between them? Why are you
> calling certain values "computations"?
> --
> 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


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Lanny Ripple
A very good point.  I even knew that implicitly but wasn't 
thinking in those terms explicitly when writing up my first post 
and it does make a difference in how you view things.


  -ljr

Jeff Polakow wrote:


Hello,

 > Look!  You are doing it again!  :)  Does that paragraph even
 > contain the word "Monad"?  :)
 >
Sorry. Your first paragraph led me to believe you were writing about 
monads.


 > I'm aware a monad is an abstraction and as such it doesn't *do*
 > anything.  My point was along the lines that you don't need to
 > know that your working in a field to be able to learn that
 >
 > 3/2 = 1.5
 >
I agree.

I think one of the problem with understanding monads comes from people 
mistakenly believing monads force an order of evaluation. This is a 
shortcoming of general Haskell tutorials which fail to convey that the 
order of evaluation is determined by data dependencies. If new 
programmers know that monads have nothing to do with forcing the order 
of evaluation when they start learning about monads, then maybe they 
will be less confused as they sort out what monads are actually used for.


-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.


--
Lanny Ripple <[EMAIL PROTECTED]>
ScmDB / Cisco Systems, Inc.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Sebastian Sylvan
On 14/08/07, Dan Piponi <[EMAIL PROTECTED]> wrote:
> On 8/14/07, Sebastian Sylvan <[EMAIL PROTECTED]> wrote:
> > I like the very light weight analogy (which works for most practical
> > uses of monads) that a monadic action is a "recipe"
>
> Many introductory programming books present the idea of a program as a
> recipe. Here's a recipe for computing factorials:
>
> fact 0 = 1
> fact n = n*fact (n-1)
>
> Where do monads come in?

Well I would try to distinguish between code that we write to compute
values, and values which represent monadic actions when coming up with
analogies. You may wish to explain code as recipes too, but I think
your students would start getting confused if you overload the same
analogy for two different things.

The point was to find some real world analogy for "abstraction of an
action". A cooking recipe fits the bill pretty well. Everyone "gets"
that you can have a "model" of "making pancake batter" in the form of
a recipe, and that you can combine such recipes with other recipes or
store them in boxes or whatever. Once you're that far along, you're
half way there in teaching them enough to be able to use most monads
in practice.


-- 
Sebastian Sylvan
+44(0)7857-300802
UIN: 44640862
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Derek Elkins
On Tue, 2007-08-14 at 09:55 -0500, Lanny Ripple wrote:
> Having just gone through all the tutorials and things (again but 
> this time I think it stuck) the Haskell community is on the wrong 
> track as far as teaching Monads to new programmers.
> 
> If I were teaching addition and multiplication to children I 
> wouldn't start with, "We'll begin by defining an algebraic 
> structure named a "Group".  From there we'll expand our concept 
> to a "Ring" and "Field".  A group is a set and a binary operator 
> usually named "+" (or sometimes "*") such that...".
> 
> No no no.  You start with, "You all know how to count from one to 
> 10.  If we have 1 item and we 'add' another 1 item we have 2 
> items.  We write this 1+1=2."

For every monad tutorial of the former type, I can find ten of the
latter.  This is not the problem.  A similar complaint is tutorials that
invoke category theory; almost none of them do this either.

What people need to do is stop reading two page blog posts by someone
who's "just got" monads and read the well-written peer-reviewed papers
by the people who clearly know what they are talking about.  Luckily,
for monads applied to Haskell we have Wadler, a witty, enjoyable and
clear writer/speaker.  All of Wadler's monad "introductions" are
readable by anyone with a basic grasp of Haskell.  You certainly don't
need to be even remotely an academic to understand them.  I'm willing to
bet that many people who say they don't understand monads and have read
"every tutorial about them" haven't read -any- of Wadler's papers.

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


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Jeff Polakow
Hello,

> Look!  You are doing it again!  :)  Does that paragraph even 
> contain the word "Monad"?  :)
> 
Sorry. Your first paragraph led me to believe you were writing about 
monads.

> I'm aware a monad is an abstraction and as such it doesn't *do* 
> anything.  My point was along the lines that you don't need to 
> know that your working in a field to be able to learn that
> 
> 3/2 = 1.5
> 
I agree.

I think one of the problem with understanding monads comes from people 
mistakenly believing monads force an order of evaluation. This is a 
shortcoming of general Haskell tutorials which fail to convey that the 
order of evaluation is determined by data dependencies. If new programmers 
know that monads have nothing to do with forcing the order of evaluation 
when they start learning about monads, then maybe they will be less 
confused as they sort out what monads are actually used for.

-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: [Haskell-cafe] Explaining monads

2007-08-14 Thread Dan Piponi
On 8/14/07, Sebastian Sylvan <[EMAIL PROTECTED]> wrote:
> I like the very light weight analogy (which works for most practical
> uses of monads) that a monadic action is a "recipe"

Many introductory programming books present the idea of a program as a
recipe. Here's a recipe for computing factorials:

fact 0 = 1
fact n = n*fact (n-1)

Where do monads come in?
--
Dan
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Dan Piponi
On 8/14/07, Jeff Polakow <[EMAIL PROTECTED]> wrote:
> One general intuition about monads is that they represent computations
> rather than simple (already computed) values:

> x :: Int   -- x is an Int
> x :: Monad m => m Int  -- x is a computation of an Int

What's a "computation"? It seems to me that in a lazy language, x::Int
represents a computation of an int, not an "already computed" value.
x::[Int] is a computation that returns multiple values. x::(Int,Int)
is a computation that returns a pair of values. x::() is a computation
that returns nothing. x::Map a b is a computation that gives a way to
associate values of type a with values of type b. Some of these are
monads, some are not. What's the difference between them? Why are you
calling certain values "computations"?
--
Dan
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Alex Queiroz
Hallo,

On 8/14/07, Jeff Polakow <[EMAIL PROTECTED]> wrote:
>
> Hello,
>
> There is clearly a problem with the Haskell/monad tutorials out there...
>
> > The tutorials seriously need to step back and start with
>  > something like, "To enforce order of evaluation we evaluate
>  > closures* returning a defined type.  The first closure will feed
>  > its result to the second which will in turn feed it's result to
>  > the third.  Since the third closure can't be evaluated without
>  > having the results from the second and first (and thus they had
>  > to be evaluated earlier in time) we get a defined evaluation
>  > sequence.  Here are some examples..."
>  >
> The style of this description is nice; however the description itself is
> wrong.
>
> Monads DO NOT determine order of evaluation. Previous posts on this thread
> give several examples.
>

 And his point was completely missed.

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


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Lanny Ripple
Look!  You are doing it again!  :)  Does that paragraph even 
contain the word "Monad"?  :)


I'm aware a monad is an abstraction and as such it doesn't *do* 
anything.  My point was along the lines that you don't need to 
know that your working in a field to be able to learn that


   3/2 = 1.5

.

  -ljr

Jeff Polakow wrote:


Hello,

There is clearly a problem with the Haskell/monad tutorials out there...

 > The tutorials seriously need to step back and start with
 > something like, "To enforce order of evaluation we evaluate
 > closures* returning a defined type.  The first closure will feed
 > its result to the second which will in turn feed it's result to
 > the third.  Since the third closure can't be evaluated without
 > having the results from the second and first (and thus they had
 > to be evaluated earlier in time) we get a defined evaluation
 > sequence.  Here are some examples..."
 >
The style of this description is nice; however the description itself is 
wrong.


Monads DO NOT determine order of evaluation. Previous posts on this 
thread give several examples.


In lazy languages, data dependencies determine the order of evaluation. 
X must be evaluated before Y if Y depends upon the result of X. You can 
force the order of evaluation without using a monad just as you can have 
a monad which does not determine the order in which things get evaluated.


 From the point of view of a programmer, a monad is simply a useful 
(higher-order) combinator pattern. All monadic code can be flattened by 
replacing occurrences of bind (>>=) with it's definition.


One general intuition about monads is that they represent computations 
rather than simple (already computed) values:


x :: Int   -- x is an Int

x :: Monad m => m Int  -- x is a computation of an Int

x :: [Int] -- x is a computation of an Int which can 
return multiplie values


x :: Maybe Int -- x is a computation of an Int which might 
fail (return Nothing)


x :: State s Int   -- x is a computation of an Int which relies 
on, and returns (possibly modified)
   --   a value of type s. Note: State s Int is 
isomorphic to: s -> (Int,s)


x :: IO Int-- x is a computation of an Int which can 
interact with the outside world.


Return explains how to make a simple computation which returns a 
specified value.
Bind explains how to use the result of a computation to compute 
something else.
 
-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.


--
Lanny Ripple <[EMAIL PROTECTED]>
ScmDB / Cisco Systems, Inc.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Jeff Polakow
Hello,

There is clearly a problem with the Haskell/monad tutorials out there...

> The tutorials seriously need to step back and start with 
> something like, "To enforce order of evaluation we evaluate 
> closures* returning a defined type.  The first closure will feed 
> its result to the second which will in turn feed it's result to 
> the third.  Since the third closure can't be evaluated without 
> having the results from the second and first (and thus they had 
> to be evaluated earlier in time) we get a defined evaluation 
> sequence.  Here are some examples..."
> 
The style of this description is nice; however the description itself is 
wrong. 

Monads DO NOT determine order of evaluation. Previous posts on this thread 
give several examples. 

In lazy languages, data dependencies determine the order of evaluation. X 
must be evaluated before Y if Y depends upon the result of X. You can 
force the order of evaluation without using a monad just as you can have a 
monad which does not determine the order in which things get evaluated.

>From the point of view of a programmer, a monad is simply a useful 
(higher-order) combinator pattern. All monadic code can be flattened by 
replacing occurrences of bind (>>=) with it's definition.

One general intuition about monads is that they represent computations 
rather than simple (already computed) values:

x :: Int   -- x is an Int

x :: Monad m => m Int  -- x is a computation of an Int

x :: [Int] -- x is a computation of an Int which can 
return multiplie values

x :: Maybe Int -- x is a computation of an Int which might 
fail (return Nothing)

x :: State s Int   -- x is a computation of an Int which relies 
on, and returns (possibly modified) 
   --   a value of type s. Note: State s Int is 
isomorphic to: s -> (Int,s)

x :: IO Int-- x is a computation of an Int which can 
interact with the outside world.

Return explains how to make a simple computation which returns a specified 
value.
Bind explains how to use the result of a computation to compute something 
else.
 
-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: [Haskell-cafe] Explaining monads

2007-08-14 Thread Sebastian Sylvan
On 14/08/07, Lanny Ripple <[EMAIL PROTECTED]> wrote:
> Having just gone through all the tutorials and things (again but
> this time I think it stuck) the Haskell community is on the wrong
> track as far as teaching Monads to new programmers.
>
> If I were teaching addition and multiplication to children I
> wouldn't start with, "We'll begin by defining an algebraic
> structure named a "Group".  From there we'll expand our concept
> to a "Ring" and "Field".  A group is a set and a binary operator
> usually named "+" (or sometimes "*") such that...".
>
> No no no.  You start with, "You all know how to count from one to
> 10.  If we have 1 item and we 'add' another 1 item we have 2
> items.  We write this 1+1=2."
>
> The tutorials seriously need to step back and start with
> something like, "To enforce order of evaluation we evaluate
> closures* returning a defined type.  The first closure will feed
> its result to the second which will in turn feed it's result to
> the third.  Since the third closure can't be evaluated without
> having the results from the second and first (and thus they had
> to be evaluated earlier in time) we get a defined evaluation
> sequence.  Here are some examples..."
>
> (* Even using the word 'closure' is scary for those not familiar
> with them.)
>
> Then, like "Monads For Functional Programming" (the paper that
> finally clicked Monads for me) you point out that evaluating all
> these closures returning a defined type in various ways form a
> structure (which you can then explain) and we can use that
> structure and change out the underlying effect(s) as needed.
>
> Now of course if your new programmer has the the necessary
> background you can throw them in the deep end.  But don't do that
> to someone coming at the language from something like Java
> learned out of a business degree course.  (My background is a CS
> degree with math minor and it still took two go-s at Haskell
> before I got as far as understanding what folks were talking
> about with Monads.  Wish I had found Wadler's MFFP the first time
> around.)  Where are the shallow end tutorials?  (Don't get me
> wrong.  The tutorials are good but there is also a place for the
> "learn-by-rote with lots of examples" ones too.)


Agreed, people tend to complicate things in the interest of being
precise, which is probably a misstake when dealing with
non-mathematicians.

I like the very light weight analogy (which works for most practical
uses of monads) that a monadic action is a "recipe" (you can even say
that they're stored in sealed envelopes to model the opaqueness of
e.g. IO). You can store recipes in boxes (data structures), pass them
around,  combine them to make new recipes etc. That's an abstraction
of "actions" that everyone is familiar with. The analogy might not fit
everything perfectly, but at least the reader will be with you from
the start, and that makes it more likely that they'll follow you when
you start diverging from the metaphor. Then you say that the GHC
runtime system is the cook, who will take the "main" recipe and follow
it.



-- 
Sebastian Sylvan
+44(0)7857-300802
UIN: 44640862
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Lanny Ripple
Having just gone through all the tutorials and things (again but 
this time I think it stuck) the Haskell community is on the wrong 
track as far as teaching Monads to new programmers.


If I were teaching addition and multiplication to children I 
wouldn't start with, "We'll begin by defining an algebraic 
structure named a "Group".  From there we'll expand our concept 
to a "Ring" and "Field".  A group is a set and a binary operator 
usually named "+" (or sometimes "*") such that...".


No no no.  You start with, "You all know how to count from one to 
10.  If we have 1 item and we 'add' another 1 item we have 2 
items.  We write this 1+1=2."


The tutorials seriously need to step back and start with 
something like, "To enforce order of evaluation we evaluate 
closures* returning a defined type.  The first closure will feed 
its result to the second which will in turn feed it's result to 
the third.  Since the third closure can't be evaluated without 
having the results from the second and first (and thus they had 
to be evaluated earlier in time) we get a defined evaluation 
sequence.  Here are some examples..."


(* Even using the word 'closure' is scary for those not familiar 
with them.)


Then, like "Monads For Functional Programming" (the paper that 
finally clicked Monads for me) you point out that evaluating all 
these closures returning a defined type in various ways form a 
structure (which you can then explain) and we can use that 
structure and change out the underlying effect(s) as needed.


Now of course if your new programmer has the the necessary 
background you can throw them in the deep end.  But don't do that 
to someone coming at the language from something like Java 
learned out of a business degree course.  (My background is a CS 
degree with math minor and it still took two go-s at Haskell 
before I got as far as understanding what folks were talking 
about with Monads.  Wish I had found Wadler's MFFP the first time 
around.)  Where are the shallow end tutorials?  (Don't get me 
wrong.  The tutorials are good but there is also a place for the 
"learn-by-rote with lots of examples" ones too.)


  $0.02,
  -ljr

PS - Not so much directed at Ronald's post but his was convenient 
to get me on my soapbox.


Ronald Guida wrote:

My present goal is to understand monads well enough to be able to
explain them to others.  I wonder if it's possible to create a
tutorial that explains monads well enough so that they just "make
sense" or "click" for people.

--
Lanny Ripple <[EMAIL PROTECTED]>
ScmDB / Cisco Systems, Inc.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Dougal Stanton
On 14/08/07, Ronald Guida <[EMAIL PROTECTED]> wrote:

> My present goal is to understand monads well enough to be able to
> explain them to others.  I wonder if it's possible to create a
> tutorial that explains monads well enough so that they just "make
> sense" or "click" for people.

It seems everyone wants to do this, with not much success! :-(

>From reading this thread (piecemeal rather than in one concentrated
session) I get the impression that no-one agrees on what, if anything,
a monad is. If there were a wiki page What_Is_A_Monad and all these
ideas were whittled down whenever a counter-proof (such as Identity or
Reader) were raised --- what would be left?

I get the impression it would look like this:

>  (return x) >>= f == f x
>  m >>= return == m
>  (m >>= f) >>= g == m >>= (\x -> f x >>= g)

And then where would we be? ;-)

I say all this from the point of view of someone who has a reasonably
robust intuitive idea of monads that still fails to encompass the List
monad. I too would like to understand the overall idea to this monad
malarkey...

Cheers,

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


Re: [Haskell-cafe] Explaining monads

2007-08-14 Thread Kim-Ee Yeoh


Ronald Guida wrote:
> 
> Here is the brief explanation I came up with:
>  > Arrows and monads are abstract data types used to construct Domain
>  > Specific Embedded Languages (DSELs) within Haskel.  A simple arrow
>  > provides a closed DSEL.  A monad is a special type of arrow that
>  > creates an open DSEL by allowing users to embed arbitrary Haskel
>  > within it.
> 
> Is this an accurate explanation?  I hate to feed a fire, but is
> "Domain Specific Embedded Language" a well-defined phrase, or is it
> just another example of linguistic cruft?
> 

Neither. It's the latest buzzword, joining the likes of AOP and
Generics. Haskell has an opportunity to ride the DSEL bandwagon,
and like most such opportunities it can take her where she don't
want to go.


Ronald Guida wrote:
> 
> Also, is this a /useful/ explanation, or have I simply hidden the
> complexity by invoking the concepts of ADTs and DSELs?
> 

It certainly has a nice spin. I've nominated you to the Monad
Marketing Team already.

-- 
View this message in context: 
http://www.nabble.com/Explaining-monads-tf4244948.html#a12140216
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

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


Re: [Haskell-cafe] Explaining monads

2007-08-13 Thread Ronald Guida

Ronald Guida wrote:
> Given the question "What is a Monad", I would have to say "A Monad is
> a device for sequencing side-effects."

peterv <[EMAIL PROTECTED]> wrote:
> "Side-effects" is a piece of linguistic cruft played fast-and-loose
> by too many people in this game. "Sequencing" suffers the same
> disease.

Gregory Propf wrote:
> I made this mistake myself at first too.  It seems that the Monad =
> "side effect machine" error is common to Haskell newbies.  Probably
> to do with the fact that the first thing every programmer wants to
> do is write a hello world program and for that you need the IO Monad
> which requires some explanation of how a Monad can allow for side
> effects (at least the IO Monad). - Greg

Eariler in this thread, I had a conversation with several people
regarding monads and arrows.  My goal was to try to come up with a
brief explanation.  I realized that "sequencing side-effects" is a
simplistic and incorrect view, so now I'm thinking in terms of DSELs.

I have heard that writing a monad tutorial is something people do when
they finally understand monads.  I interpret this observation to mean
that either (1) monads (and arrows) are just difficult things, or (2)
most of the existing explanations and tutorials are somehow inadequate
or incomplete.

My present goal is to understand monads well enough to be able to
explain them to others.  I wonder if it's possible to create a
tutorial that explains monads well enough so that they just "make
sense" or "click" for people.

Here is the brief explanation I came up with:
> Arrows and monads are abstract data types used to construct Domain
> Specific Embedded Languages (DSELs) within Haskel.  A simple arrow
> provides a closed DSEL.  A monad is a special type of arrow that
> creates an open DSEL by allowing users to embed arbitrary Haskel
> within it.

Is this an accurate explanation?  I hate to feed a fire, but is
"Domain Specific Embedded Language" a well-defined phrase, or is it
just another example of linguistic cruft? If DSEL is cruft, then is
there a better way to briefly explain monads and arrows?

Also, is this a /useful/ explanation, or have I simply hidden the
complexity by invoking the concepts of ADTs and DSELs?

-- Ron

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


Re: [Haskell-cafe] Explaining monads

2007-08-13 Thread Gregory Propf
I made this mistake myself at first too.  It seems that the Monad = "side 
effect machine" error is common to Haskell newbies.  Probably to do with the 
fact that the first thing every programmer wants to do is write a hello world 
program and for that you need the IO Monad which requires some explanation of 
how a Monad can allow for side effects (at least the IO Monad). - Greg

- Original Message 
From: peterv <[EMAIL PROTECTED]>
To: Kim-Ee Yeoh <[EMAIL PROTECTED]>; haskell-cafe@haskell.org
Sent: Monday, August 13, 2007 10:31:48 AM
Subject: RE: [Haskell-cafe] Explaining monads


Ronald Guida wrote:
> 
> Given the question "What is a Monad", I would have to say "A Monad is
> a device for sequencing side-effects."
> 

There are side-effects and there are side-effects. If the only
monad you use is Maybe, the only side-effect you get is a slight
warming of the CPU.



"Side-effects" is a piece of linguistic cruft played fast-and-loose
by too many people in this game. "Sequencing" suffers the same 
disease.

 





   

Sick sense of humor? Visit Yahoo! TV's 
Comedy with an Edge to see what's on, when. 
http://tv.yahoo.com/collections/222___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


RE: [Haskell-cafe] Explaining monads

2007-08-13 Thread Derek Elkins
On Mon, 2007-08-13 at 19:31 +0200, peterv wrote:
> When I read "side-effects", I understand it as "unwanted effects", like
> "aliasing", and "effects depending on the order of execution". I'm not sure
> if my understanding here is correct. I hope Haskell does not allow
> "side-effects" but only "effects", meaning the monads do not allow you to
> write the typical ill-behaving code you get when doing real imperative
> programming, enforcing a single wiring of execution, not allowing the
> capture of the RealWorld object. In Concurrent Clean special compiler
> support is present to enforce "uniqueness typing", and in Haskell special
> compiler support is available to make the RealWorld object not available at
> runtime (so e.g. you can't put the RealWorld object in a list). Is this
> correct? 

Monads certainly do allow "side-effects" in that way.  Heck, without
allowing aliasing there wouldn't be much to compel the use of
mutability.  Aliasing is the great boon and great curse of imperative
programming.  Order of execution issues are tricky.  On the one hand,
you must always (directly or indirectly) specify the order of execution,
so technically there's no uncertainty. On the other hand, there are two
distinct definitions of liftM2,
liftM2'1 f ma mb = do a <- ma; b <- mb; return (f a b) -- and
liftM2'2 f ma mb = do b <- mb; a <- ma; return (f a b)
Note that order of -evaluation- is moot (at least as much as it is for
any term).  Laziness does not come into it (unless you use lazy IO, in
which case you get what you deserve.)

> BTW: What is the correct word in Haskell for "object"? I mean the (lazy)
> value you get when evaluating a data constructor? 

What you said doesn't really make much sense, but I think the(/a) word you want 
is a "thunk".

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


RE: [Haskell-cafe] Explaining monads

2007-08-13 Thread peterv
When I read "side-effects", I understand it as "unwanted effects", like
"aliasing", and "effects depending on the order of execution". I'm not sure
if my understanding here is correct. I hope Haskell does not allow
"side-effects" but only "effects", meaning the monads do not allow you to
write the typical ill-behaving code you get when doing real imperative
programming, enforcing a single wiring of execution, not allowing the
capture of the RealWorld object. In Concurrent Clean special compiler
support is present to enforce "uniqueness typing", and in Haskell special
compiler support is available to make the RealWorld object not available at
runtime (so e.g. you can't put the RealWorld object in a list). Is this
correct? 

BTW: What is the correct word in Haskell for "object"? I mean the (lazy)
value you get when evaluating a data constructor? 

-Original Message-
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of Kim-Ee Yeoh
Sent: Monday, August 13, 2007 15:30
To: haskell-cafe@haskell.org
Subject: Re: [Haskell-cafe] Explaining monads



Ronald Guida wrote:
> 
> Given the question "What is a Monad", I would have to say "A Monad is
> a device for sequencing side-effects."
> 

There are side-effects and there are side-effects. If the only
monad you use is Maybe, the only side-effect you get is a slight
warming of the CPU.

Dave Menendez pointed to that fine Wadler link earlier. Please read
it. To wit, in Section 2: "Explaining Monads" the "essence of an
algorithm can become buried under the plumbing required to carry
data from its point of creation to its point of use." Monads can
help keep the clarity of your code untrammelled by providing
implicit plumbing, "side-channels" if you prefer, when data is
moved around.

In fact if you follow Wadler all the way to his monadic expression
evaluator, you see that you could modularize your code in awesomely
cool ways. You get to see how the kernel of the expression
evaluator could be written for a generic monad and compiled
once-and-for-all. Any additional feature (the "variations") is
coded by enriching the monad.

Monads are powerful devices for modularizing code. Available for
free. Only in Haskell (thanks to type classes!). Get them today.

"Side-effects" is a piece of linguistic cruft played fast-and-loose
by too many people in this game. "Sequencing" suffers the same 
disease.

-- 
View this message in context:
http://www.nabble.com/Explaining-monads-tf4244948.html#a12126170
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

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

No virus found in this incoming message.
Checked by AVG Free Edition. 
Version: 7.5.476 / Virus Database: 269.11.15/949 - Release Date: 12/08/2007
11:03
 

No virus found in this outgoing message.
Checked by AVG Free Edition. 
Version: 7.5.476 / Virus Database: 269.11.15/949 - Release Date: 12/08/2007
11:03
 

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


Re: [Haskell-cafe] Explaining monads

2007-08-13 Thread Kim-Ee Yeoh


Ronald Guida wrote:
> 
> Given the question "What is a Monad", I would have to say "A Monad is
> a device for sequencing side-effects."
> 

There are side-effects and there are side-effects. If the only
monad you use is Maybe, the only side-effect you get is a slight
warming of the CPU.

Dave Menendez pointed to that fine Wadler link earlier. Please read
it. To wit, in Section 2: "Explaining Monads" the "essence of an
algorithm can become buried under the plumbing required to carry
data from its point of creation to its point of use." Monads can
help keep the clarity of your code untrammelled by providing
implicit plumbing, "side-channels" if you prefer, when data is
moved around.

In fact if you follow Wadler all the way to his monadic expression
evaluator, you see that you could modularize your code in awesomely
cool ways. You get to see how the kernel of the expression
evaluator could be written for a generic monad and compiled
once-and-for-all. Any additional feature (the "variations") is
coded by enriching the monad.

Monads are powerful devices for modularizing code. Available for
free. Only in Haskell (thanks to type classes!). Get them today.

"Side-effects" is a piece of linguistic cruft played fast-and-loose
by too many people in this game. "Sequencing" suffers the same 
disease.

-- 
View this message in context: 
http://www.nabble.com/Explaining-monads-tf4244948.html#a12126170
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

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


Re: [Haskell-cafe] Explaining monads

2007-08-13 Thread Brian Brunswick
On 11/08/07, Ronald Guida <[EMAIL PROTECTED]> wrote:
>
>
> Here's my interpretation of the table:
>
> --
> Structure   | Subject  |  Action|  Verb  |  Result
> +--+++--
> function|  a   |  a->b  |  flip ($)  |  b
> Functor |  f a |  a->b  |  <$>   |  f b
> Applicative |  f a |  f (a->b)  |  flip <*>  |  f b
> Monad   |  m a |  a->m b|  >>=   |  m b
> Comonad |  w a |  w a->b|  =>>   |  w b
> Arrow   |  a b c   |  a c d |  >>>   |  a b d
> --



Nice

Kim-Ee Yeoh wrote:
> > ... I think you'll find that each of those structures have their
> > privileged place in your code.
>
> Agreed.  I'm still a beginner; I'm not sure how to choose one
> structure over another, at least not yet.  But that's because ...
>
> > Monads are undoubtedly more pervasive, and that could be because there
> > aren't as many arrow and comonad tutorials, atomic ones or otherwise.


And I'm trying to say that these shouldn't be separate tutorials at all -
its
much more instructive to compare and contrast.


Moreover, Comonad isn't even in the standard libraries (Hoogle returns
> no results for it).
>
> When I searched for tutorials on monads, I found lots of them.  In
> fact, I have heard that writing (yet another) monad tutorial is part
> of standard Haskell initiation.



Thats what I was doing above :-)




One thing that I keep seeing people say (not you), is that monads /sequence/
side effects. This is wrong, or at
least a limited picture.

/All/ of the above structures are about combining compatible things things
together in a row.
/None/ of them force any particular order of evaluation - that all comes
from the particular instance. So its
only a particular feature of IO that it sequences the side effects. Others
don't - we can have a lazy State
monad that just builds up big thunks.

IO could be implemented as any of the above structures, and still be
perfectly able to keep
things in order. Indeed, uniqueness types as in clean, are arguably just the
first one - function composition

functor IO would be really boring - we could just perform a sequence of
actions with no choices at all.
(But the whole sequence could be repeated, and I guess the Structure could
be nested for fixed loops)

The key to the choice of IO as a Monad comes back the the argument about
'simplicity' or what ever we
want to call it - I agree its rather context dependent, and indeed I was
rather flippant at the end of my first message

But lets look at the nature of the actual things being sequenced, the
actions above.

In only 3 cases are the actions simple enough to take a single /a/ argument.
Function a->b; Functor a->b;  Monad a->m b

In function and functor, the action takes no part in the complexity, doesn't
know about it.
In function application the action gets used (possibly) once, in functor and
monad possibly many times.
Only in Monad does the action have a say in the complexity, by returning an
possibly non-trivial m b.

So thats the reason Monads are so handy - the combined actions are simple,
but they can
at least participate - influence the flow of control if we are talking about
a IO-like Monad.

Also, arrows are supposed to be more general than both monads and
> comonads.  If I could just figure out what each structure (functor,
> monad, comonad, arrow) is doing, and compare and contrast them, then I
> probably will have made leaps of understanding.  I have a sense that
> tells me that the table above and the data structures below probably
> start to scratch the surface of understanding.
>
> --
>
>
Arrows are most general because they have full access to the complexity
going on in the
structure. Each arrow can do arbitrarily complex (possibly bidirectional)
negotiation with its
input, and possibly asynchronously arbitrarily complex negotiation with its
output. Any sort of
data can flow any way at any time, the only restriction is that for an
'Arrow a b' object, the
input side uses a's and the output b's.

Compare a monad - the input must be single, simple a's. All that can happen
is that the function gets called multiple times.

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


Re: [Haskell-cafe] Explaining monads

2007-08-12 Thread Kim-Ee Yeoh


David Menendez wrote:
> 
> This is probably because no one has found a compelling use case for
> comonadic-style programming in Haskell. There have been some
> interesting papers, such as "Comonadic functional attribute
> evaluation" by Uustalu and Vene, but nothing as compelling as Wadler's
> "Monads for functional programming".
> 

That same "Comonadic" paper describes how every zipper is a
comonad. I bet if we found more examples of zippers, comonads would
be in business. Much as I respect Huet 1997, more zipper tutorials
wouldn't harm either.

-- 
View this message in context: 
http://www.nabble.com/Explaining-monads-tf4244948.html#a12117211
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

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


Re: [Haskell-cafe] Explaining monads

2007-08-12 Thread Ronald Guida

Tillmann Rendel wrote:
> Ronald Guida wrote:
>> Here's a toy language, described by a regular expression:
>>  0(10)*110
>>
>> I want to read characters, one at a time, and eventually decide to
>> "Accept" or "Reject" a string.
>>
>> Let me try to understand my options.
>>
>> * With a simple Arrow, I can create a fixed sequence of "read"
>>   operations, and I can't act on the results (i.e. by choosing
>>   whether or not to keep reading) at run-time.
>
> Nothing stops your Arrow-based RegExp-library from defining suitable
> combinators to implement choices in RegExp's without using
> ArrowChoice or ArrowApply. But if your Arrow-type is abstract, the
> users of your library can only use the combinators you provided, so
> you can safely assume they do only RegExp parsing, and optimize your
> Arrows in the runRegExp-function for the special case of
> RegExp-matching.

So it seems I was thinking too narrowly of arrows...

If I think of an arrow as defining a Domain Specific Embedded Language
(DSEL), then with a plain arrow, users can't embed Haskel inside the
DSEL.

> But if you decide to expose ArrowApply-functionality to the users of
> your RegExp-library, they are able to define arbitrary string
> matching on top of your RegExp library, so you can't do any
> optimizations because you never know what your users decided to do.

If I think of a monad (ArrowApply) as defining a Domain Specific
Embedded Language (DSEL), then users can embed anything they want
within the DSEL.

> From a software engineering point of view, the idea of
> Arrow-and-only-Arrow is to encode the whole computation in the
> internal structure of the arrow, independent of the interpreting
> language Haskell. This internal structure could be as expressible as
> Haskell. In contrast, ArrowApply and Monad use regular Haskell
> expressions for everything Haskell can do (like if-then-else,
> recursion, ...) and only encode special operations into the internal
> structure (like access to state, nondeterminism, ...).
>
> This distinction is reflected in the treatment of variables in
> arrow-based vs. monadic code. monadic code can use normal Haskell
> variables, arrow-based code has to keep the variables "inside" the
> arrow in some structure.

So if I want to explain arrows and monads as concisely as possible:

Arrows and monads are abstract data types used to construct Domain
Specific Embedded Languages (DSELs) within Haskel.  A simple arrow
provides a closed DSEL.  A monad is a special type of arrow that
creates an open DSEL by allowing users to embed arbitrary Haskel
within it.

-- Ron

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


Re: [Haskell-cafe] Explaining monads

2007-08-12 Thread Tillmann Rendel

Ronald Guida wrote:

Here's a toy language, described by a regular expression:
 0(10)*110

I want to read characters, one at a time, and eventually decide to
"Accept" or "Reject" a string.

Let me try to understand my options.

* With a simple Arrow, I can create a fixed sequence of "read"
  operations, and I can't act on the results (i.e. by choosing
  whether or not to keep reading) at run-time.


Nothing stops your Arrow-based RegExp-library from defining suitable 
combinators to implement choices in RegExp's without using ArrowChoice 
or ArrowApply. But if your Arrow-type is abstract, the users of your 
library can only use the combinators you provided, so you can safely 
assume they do only RegExp parsing, and optimize your Arrows in the 
runRegExp-function for the special case of RegExp-matching.


But if you decide to expose ArrowApply-functionality to the users of 
your RegExp-library, they are able to define arbitrary string matching 
on top of your RegExp library, so you can't do any optimizations because 
you never know what your users decided to do.


From a software engineering point of view, the idea of 
Arrow-and-only-Arrow is to encode the whole computation in the internal 
structure of the arrow, independent of the interpreting language 
Haskell. This internal structure could be as expressible as Haskell. In 
contrast, ArrowApply and Monad use regular Haskell expressions for 
everything Haskell can do (like if-then-else, recursion, ...) and only 
encode special operations into the internal structure (like access to 
state, nondeterminism, ...).


This distinction is reflected in the treatment of variables in 
arrow-based vs. monadic code. monadic code can use normal Haskell 
variables, arrow-based code has to keep the variables "inside" the arrow 
in some structure.


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


Re: [Haskell-cafe] Explaining monads

2007-08-11 Thread Ronald Guida

Stefan O'Rear wrote:
> On Sat, Aug 11, 2007 at 03:00:04PM -0400, Ronald Guida wrote:
>> The question remains: "What is special about Monad or ArrowApply,
>> compared to Arrow?" or "What is more general about Arrow, compared
>> to Monad or ArrowApply?"
>
> If all you have is an Arrow, then you must make up your mind what
> you're going to do ahead of time.
>
> ArrowChoice gives you the ability to make basic "yes or no"
> decisions at run time.
>
> ArrowApply gives you arbitrary computed jumps.

OK, so I thought this through.

To summarize the classes of arrows:

1. Arrow is a device for sequencing side-effects in a fixed order.

> If all you have is an Arrow, then you must make up your mind what
> you're going to do ahead of time.

2. ArrowChoice is a device for sequencing side-effects in a fixed
  order with options.  Some effects can be selected at run-time, but
  (1) the available choices are fixed at compile-time and (2) options
  have to be selected before running the arrow computation.

> ArrowChoice gives you the ability to make basic "yes or no"
> decisions at run time.
BUT, you have to make these decisions before you run the arrow
computation.

3. ArrowApply is a device for sequencing side-effects, such that
  functions can dynamically choose side-effects at run-time based on
  intermediate results of arrow computations.

> ArrowApply gives you arbitrary computed jumps.

---

We know that ArrowApply is equivalent to Monad.

> Imagine trying to write an interpreter for a toy language with I/O,
> and IO is a plain Arrow and not a Monad.  You can read input and
> parse it, but you can't actually do IO because the IO you need to
> do, depends on the input you read - precisely what Arrow forbids!

Here's a toy language, described by a regular expression:
 0(10)*110

I want to read characters, one at a time, and eventually decide to
"Accept" or "Reject" a string.

Let me try to understand my options.

* With a simple Arrow, I can create a fixed sequence of "read"
  operations, and I can't act on the results (i.e. by choosing
  whether or not to keep reading) at run-time.

* With ArrowChoice, I can create a set of alternative paths for
  "read" operations, and I can choose a path at run-time, but I have
  to choose a fixed path /before/ I get to see any results.

* With ArrowApply, I can "read" one character and act on that
  character to choose what actions to perform next.  I can read
  characters until I can render an "Accept" or "Reject" decision.

Clearly, I need ArrowApply (or Monad) to get the job done.

In conclusion:

"What is special about Monad or ArrowApply, compared to Arrow?"
Arrow lets me sequence side-effects in a fixed order.  Monad lets me
dynamically choose side effects at run-time based on intermediate
results of previous side-effects.

-- Ron

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


Re: [Haskell-cafe] Explaining monads

2007-08-11 Thread Stefan O'Rear
On Sat, Aug 11, 2007 at 03:00:04PM -0400, Ronald Guida wrote:
> The question remains: "What is special about Monad or ArrowApply,
> compared to Arrow?" or "What is more general about Arrow, compared to
> Monad or ArrowApply?"

If all you have is an Arrow, then you must make up your mind what you're
going to do ahead of time.

ArrowChoice gives you the ability to make basic "yes or no" decisions at
run time.

ArrowApply gives you arbitrary computed jumps.


Sometimes it's useful to restrict what you can do.  Duponcheel and
Swierstra wrote a parser library as an Arrow; because it forced you to
decide the parsing structure ahead of time, their library had enough
information to build LR-type parsing tables, and thus to do yacc-style
error correction.  (Nobody found it useful enough to use, but it still
makes a nice demonstration of why plain Arrow is sometimes better.)

Conversely, some applications *need* the extra freedom.  Imagine trying
to write an interpreter for a toy language with I/O, and IO is a plain
Arrow and not a Monad.  You can read input and parse it, but you can't
actually do IO because the IO you need to do, depends on the input you
read - precisely what Arrow forbids!

Stefan


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


Re: [Haskell-cafe] Explaining monads

2007-08-11 Thread Ronald Guida

David Menendez wrote:
> Be sure to read sigpfe's "You could have invented monads!" and the
> Wadler paper.
>
> 


> 
>
> Most tutorials try to explain what a monad *is*, but these focus
> more on why they're a useful way to organize code. In my experience,
> being able to use a monad is more important than understanding the
> theory.

Hey, now I know what a monad is!  What I missed in all those tutorials
is that a monad is an *abstract base class*.  With this realization,
which I had after reading the sigfpe tutorial, everything makes sense
for me.

To review a basic OOP example, I can't illustrate what a Vehicle *is*
in general terms.  I can illustrate a Bicycle, a Car, a Boat, a Plane,
a Submarine, a Hovercraft, a LARC-V, and many other examples of
instances of /subclasses/ of Vehicle, but I can't find anything that's
/just/ a Vehicle.  In OOP, Vehicle is an abstract base class.

The same thing applies for a Monad.  I can look at lots and lots of
instances, like Maybe, Either, List, State, Reader, Writer, IO, and
lots of others, but I can't produce an example that's /just/ a Monad.
Monad is an abstract base class, too.

Now if I had to explain "What is a Vehicle", I would have to say "A
Vehicle is a device that provides transportation."  When asked for
more details, I can specify the interface and provide examples of
instances.

 Interface for Vehicle: load, unload, goto
 Instances of Vehicle: Bicycle, Car, Plane, Boat, etc.

Given the question "What is a Monad", I would have to say "A Monad is
a device for sequencing side-effects."  When asked for more details, I
can specify the interface and provide examples of instances.

 Interface for Monad: return, bind
 Instances of Monad: Maybe, Either, List, State, etc.

What is particularly stupefying for me is that I missed the fact that
Monad is "obviously" an abstract base class: Monad is declared as a
type-class!

Now the hard part.  As far I currently know - and I could be wrong:

(1) Monad, Comonad and Arrow are all abstract base classes.

(2) Monad, Comonad and Arrow are all devices for sequencing
   side-effects.

(3) Monad and Comonad are both specializations of Arrow.

Given the question "What is an Arrow", I would have to say "An Arrow
is a device for sequencing side-effects."  When asked for more
details, I can specify the interface and provide examples of
instances.

This leads directly to the question "What makes a Monad special,
compared to an Arrow?"  Right now, the clues I have are:

(1) Every monad is equivalent to a Kleisli arrow.

(2) The ArrowApply class is equivalent to the Monad class.

I can restate the question: "What is special about ArrowApply,
compared to Arrow?"  I see that an arrow accepts some inputs, performs
a computation, possibly with side-effects, and generates some outputs.

In particular, suppose I create instances of Arrow that accept two
inputs (as a pair) and produce one output.  Some of these instances
(i.e. ArrowApply) are special: I can provide, as the two inputs, (1)
an Arrow that accepts one input and one output, and (2) an input
suitable for that Arrow.  The output that I get is the result of
feeding input (2) to input (1) to get a result, *and* somehow
combining the side-effects of both arrows.

The only way an ArrowApply can combine the side effects of two arrows
and still obey the Arrow laws is through an operation that takes an
(arrow nested inside an arrow) and collapses it into a sigle arrow.
That's exactly what "join" does for monads.  So, ArrowApply is
special, compared to Arrow, because ArrowApply has a join operation,
but Arrow doesn't.  Clear as mud!

The question remains: "What is special about Monad or ArrowApply,
compared to Arrow?" or "What is more general about Arrow, compared to
Monad or ArrowApply?"

-- Ron

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


Re: [Haskell-cafe] Explaining monads

2007-08-11 Thread Kim-Ee Yeoh


Ronald Guida wrote:
> 
> Here's my interpretation of the table:
> 
> --
>  Structure   | Subject  |  Action|  Verb  |  Result
>  +--+++--
>  function|  a   |  a->b  |  flip ($)  |  b
>  Functor |  f a |  a->b  |  <$>   |  f b
>  Applicative |  f a |  f (a->b)  |  flip <*>  |  f b
>  Monad   |  m a |  a->m b|  >>=   |  m b
>  Comonad |  w a |  w a->b|  =>>   |  w b
>  Arrow   |  a b c   |  a c d |  >>>   |  a b d
> --
> 

This is the first time I've seen <$>. What a pleasing synonym for fmap. To
maintain a similar order of parameters, I think you'd want "flip <$>" up
there.


Ronald Guida wrote:
> 
> --
> Foo   a   = Foo { runFoo ::a } -- Functor
> State   s a   = State   { runState   :: s  -> (a, s) } -- Monad
> Context c a   = Context { runContext :: (a, c) ->  a } -- Comonad
> Thing   s a b = Thing   { runThing   :: (a, s) -> (b, s) } -- Arrow???
> --
> 

I believe there is a way to see all of the above as forms of "generalized
application" although not in the way presented here. (I thank Brian for
pointing to the possibility of a unified treatment in the first place.) 

A point in common among your run* functions is that you can always observe
the instance of type (a) in (m a :: Monad a). But monads are equipped with
(return :: a -> m a), not (coreturn :: m a -> a). Your 2nd table is more
about comonads, at least the coreturn aspect, than about whatever unity
you're hoping to achieve. There's more about coreturn here:
http://www.haskell.org/pipermail/haskell-cafe/2007-August/030153.html

So we need to explore "generalized application" without being too explicit
about "unwrapping" monads nor "wrapping" comonads. Why? Because being too
explicit invariably locks us into one particular instantiation and the
generalization goes poof! Think of all the otherwise rich and creative
papers written on the IO monad and its innards. 

The instances of monads I've seen are in themselves too sexy (probabilistic
modelling! digital circuit simulation! IO! concurrency!) that they end up
overwhelming the essence of monadism pregnant within. Better to start with
something boring. Like the Maybe monad.

Feck heh, "The essence of monadism pregnant within." Another fine title for
another monad tutorial.

-- 
View this message in context: 
http://www.nabble.com/Explaining-monads-tf4244948.html#a12103564
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

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


Re: [Haskell-cafe] Explaining monads

2007-08-11 Thread Donald Bruce Stewart
ronguida:
> 
> > Monads are undoubtedly more pervasive, and that could be because there
> > aren't as many arrow and comonad tutorials, atomic ones or otherwise.
> 
> Moreover, Comonad isn't even in the standard libraries (Hoogle returns
> no results for it).
> 
> When I searched for tutorials on monads, I found lots of them.  In
> fact, I have heard that writing (yet another) monad tutorial is part
> of standard Haskell initiation.
> 

Regarding the available tutorials, I've collected them under each
flavour here:

haskell.org/haskellwiki/Blog_articles/Monads 

Including 42 monad tutorials, 6 arrow tutorials, and 3 comonad
tutorials, and 0 on applicative functors.

The source for the `standard' (only) comonad library is available from
one of the sigfpe tutorials, but really should be on hackage.

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


Re: [Haskell-cafe] Explaining monads

2007-08-11 Thread David Menendez
On 8/10/07, Ronald Guida <[EMAIL PROTECTED]> wrote:
>
> Kim-Ee Yeoh wrote:
>  > Monads are undoubtedly more pervasive, and that could be because there
>  > aren't as many arrow and comonad tutorials, atomic ones or otherwise.
>
> Moreover, Comonad isn't even in the standard libraries (Hoogle returns
> no results for it).

This is probably because no one has found a compelling use case for
comonadic-style programming in Haskell. There have been some
interesting papers, such as "Comonadic functional attribute
evaluation" by Uustalu and Vene, but nothing as compelling as Wadler's
"Monads for functional programming".

> In my case, I have started to formulate my own idea for what a monad
> tutorial should be; I might attempt to write one, too.

Be sure to read sigpfe's "You could have invented monads!" and the Wadler paper.




Most tutorials try to explain what a monad *is*, but these focus more
on why they're a useful way to organize code. In my experience, being
able to use a monad is more important than understanding the theory.

> Also, arrows are supposed to be more general than both monads and
> comonads.  If I could just figure out what each structure (functor,
> monad, comonad, arrow) is doing, and compare and contrast them, then I
> probably will have made leaps of understanding.

Arrows are more general than monads and comonads in the sense that you
can create an arrow corresponding to any particular monad and comonad,
but there are also arrows which correspond to neither.

Functors are more general than monads and comonads simply because
every monad and comonad is a functor with additional operations. (This
can be obscured by the fact that the Haskell Prelude doesn't define
Monad as a subclass of Functor.)
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Explaining monads

2007-08-10 Thread Ronald Guida

Brian Brunswick wrote:
>   g  f   ???  g ??? f
>
> application  a a->b  flip ($) b
> monad bind   m a   a->m b>>=  m b
> comonad cobind   w a   w a->b=>>  w b
> arrowarr a b   arr b c   >>>  arr a c

Kim-Ee Yeoh wrote:
> Fmap's missing: m a, a->b, flip fmap, m b. You might want to throw in
> Applicative there too: m a, m (a->b), flip (<*>), m b.

Here's my interpretation of the table:

--
Structure   | Subject  |  Action|  Verb  |  Result
+--+++--
function|  a   |  a->b  |  flip ($)  |  b
Functor |  f a |  a->b  |  <$>   |  f b
Applicative |  f a |  f (a->b)  |  flip <*>  |  f b
Monad   |  m a |  a->m b|  >>=   |  m b
Comonad |  w a |  w a->b|  =>>   |  w b
Arrow   |  a b c   |  a c d |  >>>   |  a b d
--

Kim-Ee Yeoh wrote:
> ... I think you'll find that each of those structures have their
> privileged place in your code.

Agreed.  I'm still a beginner; I'm not sure how to choose one
structure over another, at least not yet.  But that's because ...

> Monads are undoubtedly more pervasive, and that could be because there
> aren't as many arrow and comonad tutorials, atomic ones or otherwise.

Moreover, Comonad isn't even in the standard libraries (Hoogle returns
no results for it).

When I searched for tutorials on monads, I found lots of them.  In
fact, I have heard that writing (yet another) monad tutorial is part
of standard Haskell initiation.

In my case, I have started to formulate my own idea for what a monad
tutorial should be; I might attempt to write one, too.

I read several monad tutorials, but I could not understand them at
first.  Monad transformers are even worse.  I had to sit, *think*,
draw diagrams, *think* some more, review several advanced tutorials,
and *think* even more.  I also looked up comonads, arrows, and
category theory.  Finally, monads (and monad transformers) started to
make sense for me.

I still don't understand monads just yet; but that's because my
self-test for understanding something is whether I feel I could
explain it to someone else and have it make sense.

I suppose that in order to understand monads, I need to actually *use*
some monads, and see them in action on something real (like an actual
algorithm) that I can relate to.  Learning feels like climbing a
mountain; much time and hard work is spent on the ascent, but new
understanding is achieved in the process.  Once I reach the top of the
mountain, the question is how to make the mountain easier to climb for
the next person.

My thinking is that the ultimate goal is to /invert/ the mountain,
such that the people can /ride/ the mountain (which still requires
some work) and gain new understanding in the process.  What I obtain
on the way up the mountain, future people would obtain, far more
efficiently, on the way /down/ the (inverted) mountain.

What I would like to see in a monad tutorial are some good real-use
examples that demonstrate /just/ monads.  I found it extremely helpful
to see an example of monads being used to compute probabilities and
drug test false-alarm rates.  This application seemed to used /just/
monads, without a lot of extra programming complexity on top, and it
provided a "real" example.  This is the sort of thing, combined with
the background of "what is a monad", that I think would make a really
good tutorial.

The "monadic lovers" story, in my opinion, provides an example that's
too contrived and simplistic.

On the other extreme, I found an example of arrows being used in a
digital circuit simulator.  As a tutorial on arrows, I would find this
too complex because there is too much "stuff" built up on top of the
arrows.  The concept of an arrow is lost in the complexity of
"special" classes like the ArrowCircuit class that was actually used
to simulate a circuit.  (Note: The circuit used in the example was
trivial, moreover my background is electrical engineering with a focus
on digital circuits.)

I found an example of a comonad being used to simulate a cellular
automaton; I found this example helpful, although it might be a little
too complex.

I think that what would make a truly great tutorial would be a
tutorial (or a series of tutorials) that starts with a "real" area of
exploration and proceeds to incrementally develop programs.  Each
increment would incorporate a new "bite" from the area of exploration,
which would cause an increase in complexity.  As the programs get
complicated, the monad (or comonad, or arrow) is introduced by
factoring the appropriate pattern out the code and then simplifying.

The tutorial might (1) state the monad laws and say "this is what
defines a monad", (2) say something li

Re: [Haskell-cafe] Explaining monads

2007-08-10 Thread Kim-Ee Yeoh


Brian Brunswick-5 wrote:
> 
>   g  f   ???  g ??? f
> 
> application  a a->b  flip ($) b
> monad bind   m a   a->m b>>=  m b
> comonad cobind   w a   w a->b=>>  w b
> arrowarr a b   arr b c   >>>  arr a c
> 

Fmap's missing: m a, a->b, flip fmap, m b. You might want to throw in
Applicative there too: m a, m (a->b), flip (<*>), m b.

Snipped: Arguments for monads being the best of the M-C-A trinity.

While I can share your enthusiasm over certain insights you've discovered
about monads, I think you'll find that each of those structures have their
privileged place in your code. You say "monads are somehow the /simplest/
way of adding general control structure on top of single values." Well sure,
for specific implicit parameters of ?simplest, ?general, and
?controlStructure. It's like saying lists are better than arrays and tuples.

Monads are undoubtedly more pervasive, and that could be because there
aren't as many arrow and comonad tutorials, atomic ones or otherwise. 


Brian Brunswick-5 wrote:
> 
> Pity the poor comonad, only really suitable for infinite sequences!
> 

Comonads are no more (exclusively) about infinite structures than monads are
(exclusively) about sequencing/imperative programming.

What's so infinite about this (specialization of the so-called Product)
comonad:

instance Comonad ((,) Bool)  where
  -- coreturn :: (Bool, r) -> r
  coreturn (b, r) = r
  -- cobind :: (Bool, r) -> ((Bool, r) -> s) -> (Bool, s)
  coextend u@(b,r) g = (b, g u)

-- 
View this message in context: 
http://www.nabble.com/Explaining-monads-tf4244948.html#a12087081
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

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