Monad Description For Imperative Programmer

This is about to put a definition/description to test. So please cooperate! ;) Is this a useful – sufficient, not complete – definition/description for a monad; for an imperative mind: (?) "A monad is like a loop that can run a new function against it's variable in each iteration." (I insist on the simplicity! And I will resist any expansion of this sentence (except for an exceptional note that I think of it hardly). I think there is not any complete definitions in computer world. At least there are many things to know when you want to use them in practice. So please have this in mind and review me!) Cheers :)

On Wednesday 01 August 2007 17:02, Kaveh Shahbazian wrote:
This is about to put a definition/description to test. So please cooperate! ;) Is this a useful – sufficient, not complete – definition/description for a monad; for an imperative mind: (?)
"A monad is like a loop that can run a new function against it's variable in each iteration."
At least in the context of Haskell, that's not correct. For a recent discussion about a simple definition of Haskell monads, see the thread beginning at: http://permalink.gmane.org/gmane.comp.lang.haskell.cafe/25882 Alexis.

This seems wrong to me. A monad is, first and foremost, a type
constructor class. I'm not sure how you can really compare that to a
loop. But perhaps the easiest way to test your definition would be to
ask this: How is, for example, the Maybe monad like a loop, in your
definition?
On 8/1/07, Kaveh Shahbazian
This is about to put a definition/description to test. So please cooperate! ;) Is this a useful – sufficient, not complete – definition/description for a monad; for an imperative mind: (?)
"A monad is like a loop that can run a new function against it's variable in each iteration."
(I insist on the simplicity! And I will resist any expansion of this sentence (except for an exceptional note that I think of it hardly). I think there is not any complete definitions in computer world. At least there are many things to know when you want to use them in practice. So please have this in mind and review me!)
Cheers :)
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On 01/08/07, Andrew Wagner
This seems wrong to me. A monad is, first and foremost, a type constructor class. I'm not sure how you can really compare that to a loop. But perhaps the easiest way to test your definition would be to ask this: How is, for example, the Maybe monad like a loop, in your definition?
I am baffled by this discussion. I thought monads were something to do with boxes of toxic apples in space? Obviously we can relate monadic apples to arrows through the William Tell analogy. And erm... yeah. Still needs a little polishing. I just hope the whole metaphor isn't rotten to the core. I will be here all week. Please, try the spice cake. Cheers, D.

On 8/1/07, Andrew Wagner
This seems wrong to me. A monad is, first and foremost, a type constructor class. I'm not sure how you can really compare that to a loop. But perhaps the easiest way to test your definition would be to ask this: How is, for example, the Maybe monad like a loop, in your definition?
As a beginner haskeller coming from an imperative experience, I think I understood what he meant. say you have this code : putStrLn "1" >> putStrLn "2" >> putStrLn "3" you can imagine each of the calls to putStrLn gets implicitly passed a variable (here, the world ) and they happen in succession so it's "like a loop". Except that a loop... loops so the comparison is far fetched.

On 8/1/07, david48
As a beginner haskeller coming from an imperative experience, I think I understood what he meant.
say you have this code :
putStrLn "1" >> putStrLn "2" >> putStrLn "3"
you can imagine each of the calls to putStrLn gets implicitly passed a variable (here, the world ) and they happen in succession so it's "like a loop".
Why isn't this "like a semicolon"? Chris

say you have this code :
putStrLn "1" >> putStrLn "2" >> putStrLn "3"
you can imagine each of the calls to putStrLn gets implicitly passed a variable (here, the world ) and they happen in succession so it's "like a loop".
It breaks down further as soon as you add any amount of complexity to the code as well. E.g.: putStrLn "1" >> getLine >>= \line -> putStrLn line >> putStrLn "end" This prints something, gets something from the user and prints it, and then prints something else. The equivalent imperative pseudo-code is something like: print "foo"; line = inputLine(); print line; print "end"; Not loop-ish at all!

On 8/1/07, Andrew Wagner
you can imagine each of the calls to putStrLn gets implicitly passed a variable (here, the world ) and they happen in succession so it's "like a loop".
It breaks down further as soon as you add any amount of complexity to the code as well. E.g.: [....] Not loop-ish at all!
I totally agree I was just stating how I understood the original poster's statement :) Personally I showed haskell to a Friend last week end. To explain some monadic code I explained it somewhat this way ( please keep in mind that I'm a beginner so the explanation I gave him is probably not accurate ) I told him that in a lazy functional programming language you can't decide when a function gets evaluated or not. I then told him that it gets problematic if you want evaluate some functions in sequence. I also told him that haskell is a pure language, that is there is no side effects in the functions. I then told him that it's a problem if you want to interact with the outside world (IO) I explained that a monad is a way to get functions evaluated in a specific order, with a type such that you can't mix actions with pure functions. I told him that monads are just a special datatype and implementation of 2 functions : - a function that lets you evaluate a function before evaluating the next one, taking the output of the first function to feed the input of the second. - a function that takes a pure value and "promotes" to the monad's type. I told him that in the case of IO the datatype in question is IO and it contains data about the outside world, but there are many other monads, but I didn't go there too much because it's not totally clear for me. He seemed to be not too much confused by the concept, so I hope that I didn't told him too much inaccuracies...

Someone asked about comparing monads to loops. If you are chiefly familiar with the i/o and state monads, that doesn't really make a lot of sense, but there IS a use of monads which IS a kind of loop. Only yesterday I was trying to read someone else's Haskell code where they had imported Control.Monad for the sake of >>= and liftM2. And how were they using >>= and liftM2? - they were using >>= on lists, where it means the same as concatMap To a beginner, I suggest that (concatMap f xs) is clearer than (xs >>= f) - they were using (liftM2 f xs ys) on lists, where it means the same as [f x y | x <- xs, y <- ys] No doubt there are people who find the monadic versions clearer. However, since the monadic operations *ARE* loops when applied to lists, it could very easily give rise to the misunderstanding that monads have something to do with looping.

My own perspective on monads is this: In procedural and OO languages, when dealing with compound data structures, we think in terms of getters (*taking data out* of the structure) and setters (*putting data in* to the structure). Languages with some impure functional features (Lisp, Scheme, Perl, Python) let you operate on lists with a "map" function ("mapcar" in Common Lisp), where instead of *taking data out* of a list, you *put a function in*, and the function manipulates each element without being aware of the context. You *turn the data structure inside-out*, as it were, so you don't have to think about how the elements are accessed. Functors are a generalization from lists to "things that can be mapped over" in general, and then monads are a generalization of functors. Haskell solves the "how can I do I/O in a pure functional language" problem by *turning the world inside-out*. Instead of taking data from the mutable outside world, using functions to manipulate it, and depositing results back into that world, you put your functions into the IO monad. It's like the joke about how a theoretical mathematician catches an elephant: build a cage, go inside, close the door, and redefine outside as inside.

On 8/2/07, Seth Gordon
Haskell solves the "how can I do I/O in a pure functional language" problem by *turning the world inside-out*. Instead of taking data from the mutable outside world, using functions to manipulate it, and depositing results back into that world, you put your functions into the IO monad.
That's a very interesting perspective. One of the questions often asked by Haskell newcomers is "how do I turn an IO a into an a?". The correct answer is that you don't; instead, you use a function (a -> m b) to indicate what you would have done with that a, and the bind operator takes care of the messy details for you. Stuart

Seth Gordon wrote:
Functors are a generalization from lists to "things that can be mapped over" in general, and then monads are a generalization of functors.
Way to go! That way lies true co/monadic enlightenment. Put another way, monads are no more about (only) IO/sequencing than fmap is about (only) lists. To learn about monadic imperative programming there are excellent places for doing so, but to learn about co/monads qua co/monads well, too bad. So here's my co/monad tutorial, or at least the barest outline of one. I guess that almost everyone can "get" fmap :: (a -> b) -> (m a -> m b) if only they got a good workout at it. So let's do lists, then trees, then your favorite exponential types, say parsers. Howsoever it's done, be sure to get a good grip on fmap. Next introduce flip (>>=) :: (a -> m b) -> (m a -> m b) as a left-sided fmap. Thinking what it means to lift just one side "nicely" should motivate the return function and monadic laws. Here "nicely" is in the sense that fmap lifts "nicely." Of course the classy way of figuring out one-sided fmap's is to contemplate both flip (>>=) and (comonadic) coextension :: (m a -> b) -> (m a -> m b) at the same time. This is my preferred approach to a co/monad tutorial. For sure, You Could Have Invented Co/Monads Too. Seth Gordon wrote:
Haskell solves the "how can I do I/O in a pure functional language" problem by *turning the world inside-out*. Instead of taking data from the mutable outside world, using functions to manipulate it, and depositing results back into that world, you put your functions into the IO monad.
But (the illusion of) taking data out from the real world, manipulating it, and then putting it back is exactly what the monadic-do syntax sugar accomplishes: do x <- inputFromRealWorld let y = manipulateIt x return y You could use (fmap manipulateIt) to "put" it into the IO monad as you describe, but monadic-do is by far the more common approach. -- View this message in context: http://www.nabble.com/Monad-Description-For-Imperative-Programmer-tf4198417.... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

Kim-Ee Yeoh wrote:
Seth Gordon wrote:
Functors are a generalization from lists to "things that can be mapped over" in general, and then monads are a generalization of functors.
Way to go! That way lies true co/monadic enlightenment.
I feel like I still don't understand comonads. Maybe I just need a Zen comaster to hit me with a costick and then I'll become coenlightened.
Haskell solves the "how can I do I/O in a pure functional language" problem by *turning the world inside-out*. Instead of taking data from the mutable outside world, using functions to manipulate it, and depositing results back into that world, you put your functions into the IO monad.
But (the illusion of) taking data out from the real world, manipulating it, and then putting it back is exactly what the monadic-do syntax sugar accomplishes:
The type system turns the world inside-out and then the do-notation provides a right-side-in syntax to code functions in the inside-out world.

On Thursday 09 August 2007 04:02, Seth Gordon wrote:
I feel like I still don't understand comonads.
If you haven't done so already, you might like to check out: "(Co)Monads for Grad Students" http://www.cas.mcmaster.ca/~carette/CAS706/F2006/presentations/comonads.pdf "Codata and Comonads in Haskell" http://www.cse.ogi.edu/PacSoft/publications/phaseiiiq10papers/codata.pdf Aelxis.
participants (10)
-
Alexis Hazell
-
Andrew Wagner
-
Christopher L Conway
-
david48
-
Dougal Stanton
-
Kaveh Shahbazian
-
Kim-Ee Yeoh
-
ok
-
Seth Gordon
-
Stuart Cook