> a <- b
> c <- f a
>
> as
>
> c <- f b
>
> In Haskell I can't. Why? b is of type IO something, whereas f expects a
> non-monadic argument.
I don't see why this is any different from say, Pascal, where you can't:
Writeln(Readln(a));
This distinction is made clear if the programmer is aware of why he's using
<- and not =. You're right that you have to become aware of the difference
between an action and a function call, but most imperative IO libraries make
a similar distinction anyway since IO functions tend not to return values
but modify a parameter (i.e., procedure vs. function is no worse!).
Plus, you can just sidestep the whole issue: no explanation, just say that
equality laws don't hold for <-.
This is obvious anyway, take:
a <- b
c <- b
d <- f a
e <- f c
is this equivalent to?:
d <- f b
e <- f b
Not if f has side-effects that affect the behavior of b.