Intuitively it seems like the applicative expression:

  (++) <$> getLine <*> getLine

should represent the same thing as the more traditional liftM2 expressions:

  do { x <- getLine; y <- getLine; return ((++) x y) }

but it seems to me that you cant directly manipulate the first into
the second.  I get:

  do x2' <- getLine
     x1 <- return ((++) x2')
     x2 <- getLine
     return (x1 x2)

the only way I can get from here to the liftM2 definition is if I
treat "x1 <- return ((++) x2')" as "let x1 = (++) x2", and then
allow it to be reordered after the second getLine.  Then it is
straightforward to reduce to the liftM2 expression above.

It seems to me that this is a valid transformation if:
   - no side effects, including pattern match errors, can occur
     in the let (or x1 <- return ...).
   - movement doesnt change the dependencies
     - x1 isnt used between the original line and its new position
     - there are no new bindings for x2' introduced between the original
       line and the new line.

Did I overlook anything?  Do any haskell implementations allow rewrites
like these to occur?

Tim Newsham
http://www.thenewsh.com/~newsham/
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to