
SevenThunders wrote:
OK so check out what really happens with liftM2. Suppose I have an IO containing an involved matrix computation called s. For simplicity we might assume that
s :: IO (Int)
and the Int is an index into an array containing a bunch of matrices in C land. Assume that s is determined by a succession of many IO operations that have lots of side effects and are fairly computationally intensive. Also assume that s is unevaluated.
Now do an operation like
q = liftM2 MultMatrix s s
What happens is that s is 'evaluated' twice when q is evaluated
e.g. do qint <- q
That becomes evident when we look at liftM2's definition liftM2 f = \a b -> do { a' <- a; b' <- b; return (f a' b') }
the statements a' <- a and b' <- b will cause s to be evaluated twice.
Therein lies my problem.
Here's your solution: do -- Compare this to liftM2 and your definition of q s' <- s -- this evaluates s once and for all qint <- return $ MultMatrix s' s' -- Ron