
G'day. On Mon, May 12, 2003 at 08:55:55PM -0700, oleg@pobox.com wrote:
But what if we add to our library joule::Energy = PhysicalUnit 1.0 cal::Energy = PhysicalUnit 4.8 second::Time = PhysicalUnit 1.0 nanosec::Time = PhysicalUnit 1.0e-9 and
scalarm:: Double -> (PhysicalUnit a1 b1 c1) -> (PhysicalUnit a1 b1 c1) x `scalarm` (PhysicalUnit y) = PhysicalUnit $ x * y
then the user can write hbar = 6.62606876e-34 `scalarm` (joule `mult` second)
That works, but IMO it's a bit unwieldy. It also doesn't help with actually defining a reasonable type signature for hbar which is the point of the exercise.
From an engineering perspective, there's little point having these expressive types if the user can't easily insert type declarations for them. I want to know where the error is, not where the error first causes a problem. To do that, I want to litter my code with as many type assertions as I can (without sacrificing readability, of course) so that the compiler can point out to me precisely where my reasoning went wrong. The equivalent of "there's a type error somewhere in this module" is not very helpful.
Incidentally, the Neg functor isn't such a bad idea, either, but I used the pair for historical reasons more than anything else. I originally thought you could save some compile time by working in non-unique whole numbers then normalising when you need a concrete type, but this reasoning turned out to be bogus. Cheers, Andrew Bromage