
Ah oops, tried to remove the Either as an optimization, forgot that IO isn't strict in the value ;-) It should probably be something like newtype IO a = IO (World -> _E a) where _E is just a box to prevent evaluation (it's used in primitive handling already). data _E a = _E a Then the IO monad would be instance Monad IO where (IO x) >>= yf = IO $ \ w -> let xe = x w in case xe of _E xv -> case yf xv of IO y -> y w (IO x) >> (IO y) = IO $ \ w -> case x w of _E _ -> y w return a = IO $ \ w -> _E a
Maybe an artificial "dependingOn", like seq but that doesn't even evaluate its argument to WHNF, is needed? (inspired by jhc's primitive dependingOn :: a -> b -> a, which is the OPPOSITE argument order (like const, rather than seq) and I'm not sure if it has the semantics I'm suggesting, but, whatever...)
Unfortunately the problem isn't (>>), it's return. return a = IO $ \ w -> a -- necessarily evaluates a = wrong Thus 'return undefined' as soon as you apply it to World (i.e. deIO it) it goes bang. The amuzing thing is that none of the conformance tests (and some of them are serious programs) rely on the laziness of IO values. Otherwise I'm sure I would have spotted my braino ;-) Tom