
The reason to combine them is that the point of abstraction between the compilers / interpreters lives in areas like "preprocess this file", "build this file", "install this library", not in operations like you mentioned:
There would be operations such as: compile a file into an object file (may be a no-op); link a bunch of object files into a package; install a package into the following package database; create an empty package database; merge two package databases; find dependencies of a module. And options like: use the following other packages, search for packages in the following package database.
Each of these operations would be a no-op for Hugs, and yet the abstraction layer that Cabal provides works quite well for Hugs. I think that if we had built a standard command-line interface between compilers, GHC and Hugs would have almost disjoint operations, and Cabal would still have to perform the same amount of work, since it couldn't actually use this interface to get its job done. peace, isaac