Juan-Carlos Gandhi (
juan_gandhi) wrote2015-01-12 07:57 pm
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
re: I/O monad
Just agreed with Runar that, well, it's not a monad, because there's no associativity (duh)
Or? (ok, ok, lax weak pseudo promonad...)
Or? (ok, ok, lax weak pseudo promonad...)
no subject
It's building a sequence of actions, so it's as associative as list.
no subject
А если смотреть операционно - то ассоциативности (и монадичности) нет.
no subject
no subject
no subject
no subject
no subject
But also see other comments with detailed paper link.
no subject
Or with the Kleisli arrow notation:
Can you give an example of m,f,g or a,b,c or whatever that violate these axioms? The linked paper seems to say nothing about it.
I have tried the usual functions like getChar and putChar, and also bottom, and they all seem to obey.
no subject
if you look at a >=> (b >=> c), what is the meaning of parentheses? Does this mean you can evaluate the term on the right of (a >=>) to get a value, which then is cobined with >=>?
Eg will it be allowed to reduce (getChar >>= (\c -> getChar >>= (\d -> print [c,d]))) by first evaluating (getChar >>= (\d -> print [c,d])) to obtain (\c -> print [c,d])?
no subject
(+) is not associative when we are talking about machine floating point numbers. (-) is not associative for any type of numbers. (++) is associative for lists.
(>=>) is associative for functions returning lists. Which means functions produced by f >=> (g >=> h) and (f >=> g) >=> h are the same, for any f g h. Again, list-returning functions are a Haskell type. What does it mean for such functions to be the same? We cannot compare functions directly, but we can say that if (f x) and (g x) are the same for all possible x, then f and g are the same.
Is (>=>) associative for functions returning IO actions? Maybe. What does it mean for two IO-action-returning functions to be the same? Well it's just like for any other function type (see above). So what does it mean for two IO actions to be the same? We cannot compare IO actions directly, but we can apply them to the ("an") outside world and observe the results. When f::IO() and g::IO(), applied to the same world, produce the same observable behaviour, we say they f and g are the same. I cannot give a formal definition to observable behaviour, or at least I cannot give one that is easy to work with. But I can damn well see when two programs in the same environment produce different results. So if there's no associativity, one should be able to observe different behaviour of f >=> (g >=> h) and (f >=> g) >=> h. So far I could not reproduce it.
no subject
But come back to the example I gave. If Haskell evaluated (getChar >>= \d -> print [c,d]) first (would that not be allowed?), to produce a function (\c -> print [c,d]), you'd notice that (getChar >>= (\c -> print [c,d])) prints characters in the order opposite to the evaluation order evaluating actions left to right. What rules forbid that evaluation order? Technically, nothing - only the beta reduction rule; which is not good enough of a promise - the beta reduction becomes dependent on evaluation order where it wasn't.
Or, like in your example with lists. World is such a datatype (and >>= is such an operation) that (World >>= World) >>= World is not the same as World >>= (World >>= World); meaning, if you have a World that is the result of combining World >>= World, you cannot insert another effect _before_ this combination. It could work in an abstract machine, but does not work in real hardware - which works sequentially - where it matters in which order the terms are reduced.
no subject
f >=> (g >=> h) means do f first, then do the combined action (g >=> h).
If you are switching the execution order around you are not doing IO.
no subject
run_io_action(f);
run_io_action(g)
(I omit parameters and results handling). Now, associativity of >=> is associativity of semicolon, so
{
run_io_action(f);
run_io_action(g);
}
run_io_action(h)
is the same as
run_io_action(f);
{
run_io_action(g);
run_io_action(h);
}
You would not execute the g;h block in the second example before you execute f.
no subject
yes, I see it is associativity of composition. So then the claim that IO is not associative is not clear again.
no subject
no subject
In the end it is associativity of composition, because everything is turned into function of World returning World.
no subject
no subject
The Kleisli arrow can be translated to
arrow(f,g,a):
u = runMonad(g,a)
v = runMonad(f,u)
return unitMonad(v)
Associativity here simply means you can inline procedure calls.