
On Tue, Jul 30, 2002 at 01:41:43PM +0100, MR K P SCHUPKE wrote:
Is there any way to do a lazy bind operation, something like
a <- $ getLine return (Constructor $ a)
this works for computations in the IO monad :-
a <- unsafeInterleaveIO getLine return (Constructor $ a)
but I need to do this for a general monad M.
I don't think this is possible. In general, you have to write separate strict and lazy binding operations. For instance, there are both ST and LazyST for state transformer monads, and the latter's >>= operation is lazy. Here's a concrete example for the basic state-carrying monad. (Not tested) newtype State s a = State { unState :: s -> (a, s) } getState = State (\s -> (s, s)) setState x = State (\s -> ((), x)) -- Monad.return returnState a = State (\s -> (a, s)) -- strict Monad.>>= State m `strictBindState` f = State (\s -> case m s of (a, s') -> unState (f a) s') -- lazy Monad.>>= State m `lazyBindState` f = State (\s -> case m s of ~(a, s) -> unState (f a) s') As you can see, the difference between lazy and strict binding is an inherent part of the definition of >>=, so there's no way to automatize it. This is kind of a shame, for I too sometimes need both lazy and strict versions of a monad transformer, but this requires two separate types with different monad instances... Lauri Alanko la@iki.fi