CC: Functional dependencies question

hbar :: (Mult Energy Time t) => t hbar = PhysicalUnit 6.62606876e-34
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) or hbar = 6.62606876e-25 `scalarm` (joule `mult` nanosec) or hbar = (6.62606876e-25/4.8) `scalarm` (cal `mult` nanosec) Can't we? Or I'm missing something? GHC seems happy. We can probably define in the library transf:: (PhysicalUnit a1 b1 c1) -> (PhysicalUnit a1 b1 c1) -> Double transf (PhysicalUnit x) (PhysicalUnit y) = x/y and write hbar = (6.62606876e-25/(cal `transf` joule)) `scalarm` (cal `mult` nanosec) P.S. Just for the record: yet another way to introduce negative numbers is through an explicit constructor Neg. For example: http://pobox.com/~oleg/ftp/Computation/type-arithmetics.html (sorry, the code uses C++ templates. The idea is just the same however: a mere Prolog in a more verbose notation). The above example demonstrates division of signed Peano numbers. The Neg constructor becomes quite handy then.

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

In article <200305130355.h4D3ttcB013484@adric.fnmoc.navy.mil>, oleg@pobox.com wrote:
Just for the record: yet another way to introduce negative numbers is through an explicit constructor Neg. For example: http://pobox.com/~oleg/ftp/Computation/type-arithmetics.html (sorry, the code uses C++ templates. The idea is just the same however: a mere Prolog in a more verbose notation). The above example demonstrates division of signed Peano numbers. The Neg constructor becomes quite handy then.
I prefer NegativeSucc, i.e. -(n+1) or -n-1. My integer types are thus T or NegativeSucc T for any natural type T, and the two don't overlap. Another trick is to use the same class for addition and subtraction: class Add a b ab | a b -> ab, ab a -> b; I found you can't build the instances if you have all three possible fundeps (because of overlaps), but you can with two. <http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/hbase/Source/HBase/TypeCa lc/>. As for dimensions, what would be most interesting would be to allow the user to add their own "basis" units, so for instance: module MyModule where import PhysicalUnits -- new basis unit type Cost = [whatever] dollar :: Cost dollar = [whatever] goldValue :: (Div Mass Cost t) => t goldValue = ... ...but that may be hard and/or messy. -- Ashley Yakeley, Seattle WA
participants (3)
-
Andrew J Bromage
-
Ashley Yakeley
-
oleg@pobox.com