
On Mar 12, 2008, at 2:10 PM, Henning Thielemann wrote:
On Wed, 12 Mar 2008, Donn Cave wrote:
On Mar 12, 2008, at 12:32 PM, Brandon S. Allbery KF8NH wrote:
Sure. It isn't a lot of code, so I subjected it to Either-ization as an experiment, and I did indeed take the monad procedural route. Monad != procedural, unless you insist on do notation. Think of it as composition (it may be easier to use (=<<) which "points
On Mar 12, 2008, at 14:17 , Donn Cave wrote: the same direction" as (.)).
Yes, I insist on do notation, because it provides a convenient binding form that works with what I'm doing - the original functional variation wasn't so suited to composition either, and used `let'.
But I see that as only syntactic - equally procedural, either way. Expressions are evaluated in a fixed order,
Do notation only looks like there are statements that are processed from the beginning to the end. But that's not true, it's still purely lazy and expressions are evaluated in the order that is forced by data dependencies.
Let me put it this way: if I write do (i, s') <- decodeInt s (v, _) <- decodeInt s' return (i, v) ... instead of, to just avoid the monad stuff case (decodeInt s) of Left e -> Left e Right (i, s') -> case (decodeInt s') of Left e -> Left e Right (v, _) -> Right (i, v) ... the `do' notation just emphasizes the procedural-ness of this computation. I can't arrive at the end, without completing these steps, whatever notation I choose. `do' just happens to be considerably more convenient. Of course data dependencies force the order of evaluation, but some of those dependencies are inevitably built into the expression: I can't evaluate the result (Right (i, _)) without evaluating the second decodeInt far enough to know that it isn't (Left _). The type that we'd need for that would be something like Either String (Int, (Either String Int)) (etc. ad nauseum as the return value gets more complex.) Well, the problem inherently requires a certain order of evaluation. But if you will just handle pattern match failure in the IO monad, then you can write a simple functional expression of the problem instead, let (i, s') = decodeInt s in let (v, _) = decodeInt s' in (i, v) ... where I think `i' can be evaluated without forcing unnecessary evaluation of v. It's clearer, and avoids unnecessary strictness! Donn Cave, donn@avvanta.com