Haskell expressions as conversion factors
How realistic is this?
It would be nice to be able to define degrees as [u| deg = (pi / 180) rad |] and have that expression spliced into convert.
This would be particularly useful for my exact real package, where any constant ratio may not be precise enough.
There are two separate issues here.
The Template Haskell quasiquoter would need to parse and splice arbitrary Haskell expressions, which in principle is possible, but would require quite a bit of work. In the short term you can always expand the TH manually, which in this case would be something like
-- [u| rad |]
type instance MkUnit "rad" = Base "rad"
instance HasCanonicalBaseUnit "rad"
-- [u| deg = (pi / 180) rad |]
type instance MkUnit "deg" = Base "deg"
instance HasCanonicalBaseUnit "deg" where
type CanonicalBaseUnit "deg" = "rad"
conversionBase _ = (pi / 180) *: [u| 1 deg/rad |]
Unfortunately there is a bigger problem, which is that at the moment conversionBase is required to be Rational rather than an arbitrary numeric type. It might be possible to generalise this and keep convert, I forget the details...
It's probably a niche request. I'd be happy to look into generalizing conversionBase myself.
I need to convert between units of degrees and radians too. When radians are defined "to require explicit conversion", as they are in the Defs module with [u| rad 1 1 |], equivalent to declareConvertibleUnit "rad" 1 "1", I haven't found a way for degrees to be setup as a conversion from radians without getting an error ...
declareConvertibleUnit "rad" 1 "1"
declareConvertibleUnit "deg" (5030569068109113 % 288230376151711744) "rad"
Couldn't match type ‘One’ with ‘Base "rad"’
In the instance declaration for ‘HasCanonicalBaseUnit "deg"’
Dumping the template splices to show the equivalence of the two forms ...
[u| rad = 1 1 |]
stack build --ghc-options='-ddump-splices -ddump-to-file'
" rad = 1 1 "
======>
type instance MkUnit "rad" = Base "rad",
instance HasCanonicalBaseUnit "rad" where
type CanonicalBaseUnit "rad" = One
conversionBase _ = Data.UnitsOfMeasure.Internal.MkQuantity 1.0
declareConvertibleUnit "rad" 1 "1"
stack build --ghc-options='-ddump-splices -ddump-to-file'
declareConvertibleUnit "rad" 1 "1"
======>
type instance MkUnit "rad" = Base "rad"
instance HasCanonicalBaseUnit "rad" where
type CanonicalBaseUnit "rad" = One
conversionBase _ = Data.UnitsOfMeasure.Internal.MkQuantity 1.0
I could setup degrees like this as a dimensionless scaling not based on radians ...
[u| deg = (5030569068109113 % 288230376151711744) 1 |]
Here's my working.