
To many questions, not enough mail. First, thanks for all your replies. Second, I stand totally corrected on the fact that we cannot break down monads. Functions of type m a->b are called impure, see also unsafePerformIO. I am questioning (a) the exact relation between monads, monadic IO, IO in general and (b) whether the impure restriction is actually a warranted restriction, which relates to, what I find, strange evaluation behavior of the IO monad. What is the difference between putStr "a", (putStr "a", putStr "a"), putStr (putStr "a"), putStr (show (putStr "a"))? At the moment objects of type IO a _only_ get evaluted when they are the _sole_ result of a Haskell program. What kind of strange dichotomy is that? Is not the _only_ interpretation of this dichotomy that objects of type IO describe impure programs (composed of actions which are only evaluated when...)? And, if so, why can't we decompose these programs (before they get evaluated)? And, if so, is not the only relation between a monad and doing functional IO that there is a monadic manner to construct descriptions of impure programs? If so, are there also non-monadic ways which might be equally interesting? As stated by Keith, deriving show for IO is possible. In such a setting putStr (putStr "a") I imagine returns "putStr \"a\"", which I find far more orthogonal than what we have now. (Have to find the reference still). Does this boil down to an impure or a pure decomposition?
From: Derek Elkins
To: "blaat blaat" , haskell-cafe@haskell.org pragmatic short one. What did we lose? Well, introspection comes to mind. A monad is strange in the sense that, actually, there does not seem to be any reason to compute its value since we cannot possibly get anything out of it. In case of IO, only the haskell interpreter can. And, introspection is a nice thing to have, especially for compiler writers. Although I think the benefits in Haskell would be limited, an application might be that I could write my own promotion functions on my own programs.
Lot's of issues with this paragraph, but here are the questions. What do you mean by "promotion function"?
Example of promotion: map f . map g = map (f . g) A promotion function would transform objects of type IO a into objects of type IO a while performing promotions. How would you write it in your
hypothetical Haskell? How is it related to IO? How do monads and/or the IO monad in particular cause problems? Why couldn't the same be done using monads or why would it be significantly harder if it can be done?
In a monadic approach, I imagine functions like "unbind" which now would break purity. [..]
I believe that central in the IO-issue is not the fact that we are using monads for IO - but that we can purely create impure programs which do the IO for us ;-), and that those do not have to be of the monadic kind.
I still stand here (but am totally willing to be corrected on this account too). Hmpf, maybe someone more enlightened should write a paper on it. Cheers, l4t3r _________________________________________________________________ MSN 8 with e-mail virus protection service: 2 months FREE* http://join.msn.com/?page=features/virus

On Thu, 14 Aug 2003, blaat blaat wrote:
To many questions, not enough mail. First, thanks for all your replies. Second, I stand totally corrected on the fact that we cannot break down monads. Functions of type m a->b are called impure,
Haskell is a pure language, so there are *no* impure functions. Expressions in haskell are also referentially transparent, except... there are a few extensions that allow one to disguise a (possibly) side-effect-full expression into one that haskell believes is RT (FFI or unsafePerformIO comes to mind). This is really unsafe, since haskell might evaluate it (which cause execution) any number of times including Zero and One Zillion. The by newbies often requested IO a -> a extraction function is a bad idea for this reason, and generally just means that the newbie has not understood how to deal with actions in haskell. It is common for Monads to have a runme function of type runme :: Monad m => m a -> a Nothing strange about that.
see also unsafePerformIO. I am questioning (a) the exact relation between monads, monadic IO, IO in general and (b) whether the impure restriction is actually a warranted restriction, which relates to, what I find, strange evaluation behavior of the IO monad.
What is the difference between putStr "a", (putStr "a", putStr "a"), putStr (putStr "a"), putStr (show (putStr "a"))?
At the moment objects of type IO a _only_ get evaluted when they are the _sole_ result of a Haskell program. What kind of strange dichotomy is that?
A haskell program has the type IO () and will be executed bu the haskell runtime. The situation is a little more fuzzy when you use a interpreter. The interpreters usualy execute entered expressions of type IO a, and evaluate all other expressions. I can agree that this might not be obvious. /Lars L

On Thursday, 2003-08-14, 13:37, CEST, blaat blaat wrote:
[...]
Hello, I don't know exactly which of the following questions have already been answered but I decided to answer them all anyway.
What is the difference between putStr "a", (putStr "a", putStr "a"), putStr (putStr "a"), putStr (show (putStr "a"))?
As I stated earlier, IO a denotes an I/O action which has a result of type a. So the above expressions have the following meaning: putStr "a": an I/O action outputting the string "a" (putStr "a",putStr "a"): a pair of two I/O actions, both outputting the string "a" (This pair is not executable like an I/O actions is.) putStr (putStr "a"): illegal expression because the argument of putStr has to be of type String but putStr "a" has type IO () putStr (show (putStr "a")): For this to work, IO () has to be an instance of class Show which roughly means it must be convertable into a string. putStr "a" is the I/O action which outputs "a" (see above). With a appropriate Show instance, show (putStr "a") would yield a string representation of this I/O action. putStr (show (putStr "a")) would be an I/O action which outputs this string representation.
At the moment objects of type IO a _only_ get evaluted when they are the _sole_ result of a Haskell program.
I/O expressions get evaluated the same way every other expression does. But theit resulting I/O actions get *executed* only under a certain condition. And the condition is that the action in question has to be a part of the main I/O action. Evaluating an expression of type IO a doesn't mean to execute it but to "calculate the I/O action". Since Haskell is pure, expression evaluation never does any I/O. I/O actions are not executed by expression evaluation but because the meaning of a Haskell program is to execute main.
What kind of strange dichotomy is that? Is not the _only_ interpretation of this dichotomy that objects of type IO describe impure programs (composed of actions which are only evaluated when...)?
Yes, they *describe* impure programs. But as I just said, evaluating the actions doesn't mean to execute them.
[...]
And, if so, is not the only relation between a monad and doing functional IO that there is a monadic manner to construct descriptions of impure programs? If so, are there also non-monadic ways which might be equally interesting?
Yes, there is nothing magical about monads. They are just an abstract concept which fits nicely in the context of building descriptions of actions. And there are other ways of constructing such descriptions (as someone already mentioned).
[...]
From: Derek Elkins
To: "blaat blaat" , haskell-cafe@haskell.org
[...]
I believe that central in the IO-issue is not the fact that we are using monads for IO - but that we can purely create impure programs which do the IO for us ;-), and that those do not have to be of the monadic kind.
Exactly.
[...]
Wolfgang
participants (3)
-
blaat blaat
-
Lars Lundgren
-
Wolfgang Jeltsch