Copyright | (C) 2014 Richard Eisenberg |
---|---|
License | BSD-style (see LICENSE) |
Maintainer | Richard Eisenberg (eir@cis.upenn.edu) |
Stability | experimental |
Portability | non-portable |
Safe Haskell | None |
Language | Haskell2010 |
This module exports Template Haskell functions to make working with
units
a little more convenient.
Documentation
evalType :: Q Type -> Q Type Source
Evaluates a type as far as it can. This is useful, say, in instance declarations:
instance Show $(evalType [t| Length |]) where ...
Without the evalType
, the instance declaration fails because Length
mentions type families, which can't be used in instance declarations.
This function is somewhat experimental, and will likely not work with more polymorphic types. (If it doesn't work, not all of the type families will be evaluated, and the instance declaration will fail. This function should never cause incorrect behavior.)
declareDimension :: String -> Q [Dec] Source
Declare a new dimension of the given name:
$(declareDimension "Length")
produces
data Length = Length instance Dimension Length
declareCanonicalUnit :: String -> Name -> Maybe String -> Q [Dec] Source
declareCanonicalUnit unit_name dim (Just abbrev)
creates a new
canonical unit (that is, it is not defined in terms of other known units)
named unit_name
, measuring dimension dim
. (dim
must be the name of
the dimension type, not data constructor.) abbrev
will be the
abbreviation in the unit's Show
instance. If no abbraviation is supplied,
then no Show
instance will be generated.
Example usage:
$(declareCanonicalUnit "Meter" ''Length (Just "m"))
declareDerivedUnit :: String -> Name -> Rational -> Maybe String -> Q [Dec] Source
declareDerivedUnit unit_name base_unit_type ratio (Just abbrev)
creates
a new derived unit, expressed in terms of base_unit_type
(which must be the
name of a type not a data constructor). ratio
says how many base units
are in the derived unit. (Thus, if unit_name
is Minute
and base_unit_type
is ''Second
, then ratio
would be 60
.) abbrev
, if supplied, becomes
the string produced in the derived unit's Show
instance. If no abbreviation
is supplied, no Show
instance is generated.
Example usage:
$(declareDerivedUnit "Minute" ''Second 60 (Just "min"))
declareMonoUnit :: String -> Maybe String -> Q [Dec] Source
declareMonoUnit unit_name (Just abbrev)
creates a new derived unit,
intended for use without unit polymorphism. The same type stands for both
the unit and dimension, and the instance of DefaultUnitOfDim
is set up
accordingly. Use this function (with the Metrology
imports) if you
don't want to bother with LCSUs and just want to get to work. The abbrev
,
if supplied, creates an appropriate Show
instance.
$(declareMonoUnit "Meter" (Just "m"))
produces all of the following
data Meter = Meter instance Dimension Meter instance Unit Meter where type BaseUnit Meter = Canonical type DimOfUnit Meter = Meter type instance DefaultUnitOfDim Meter = Meter instance Show Meter where show _ = "m"
After a declaration like this, you probably want
type Length = MkQu_U Meter
This last line is not generated, as it is easy enough for you to write,
and it involves a new name (Length
).