ozone@algorithm.com.au wrote:
We'd all love to make the lifting implicit, but no one knows how to do it without breaking the whole language.
I've heard people talk about the functional "purity" of Haskell -- you'd have to break this purity to add implicit lifting?
I don't think you would break the functional purity of Haskell if you did such a thing, but you'd probably need some new syntax to help out the type system. Perhaps something like:
assertBool "fail" $ length (<somefunc a>) == length (<somefunc b>)
So here, (<a>) performs the same function as the <- operator, but assigns the result to an "anonymous variable" and is instantly consumed by whatever function uses its value. Please don't berate me for my choice of syntax, by the way: that was just an example :).
One problem with this is that you now don't know what order those two operations take place: does "somefunc a" run first, or does "somefunc b" run first? You have this same problem in other imperative languages too; I'm not sure if, e.g. C defines an order for function evaluation to occur.
C doesn't define the order in which function arguments are evaluated, so: foo(getchar(), getchar()); could be equivalent to either: a = getchar(); b = getchar(); foo(a, b); or: a = getchar(); b = getchar(); foo(b, a); This isn't restricted to I/O, but affects any operation which has side effects, e.g. foo(++x, ++x); This is *why* I/O actions aren't treated as functions in pure functional languages. Regarding the "solution" of using liftM (liftM2 etc): these impose a left-to-right evaluation order, e.g.: liftM2 :: (Monad m) => (a -> b -> c) -> (m a -> m b -> m c) liftM2 f = \a b -> do { a' <- a; b' <- b; return (f a' b') } One consequence of this is that, even if (==) is an equivalence relation, "liftM2 (==)" may not be, as the order of the arguments is significant. More generally, lifted functions may have semantics which differ greatly from the underlying function. Personally, I'm quite happy that Haskell doesn't allow this to be hidden by implicit lifting. -- Glynn Clements <glynn.clements@virgin.net>