Open expipiplus1 opened 8 years ago
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.
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 intoconvert
.This would be particularly useful for my exact real package, where any constant ratio may not be precise enough.