units-2.4.1: Data/Metrology/LCSU.hs
{- Data/Metrology/LCSU.hs
The units Package
Copyright (c) 2013 Richard Eisenberg
rae@cs.brynmawr.edu
Defines a locally coherent system of units (LCSUs),
implemented as an association list.
An LCSU is a from base dimensions to units, thus
defining a uniquely mapping units for any dimensions.
-}
{-# LANGUAGE DataKinds, PolyKinds, TypeFamilies, TypeOperators, UndecidableInstances #-}
module Data.Metrology.LCSU (
LCSU(DefaultLCSU), DefaultUnitOfDim,
Lookup, LookupList, MkLCSU
) where
import Data.Metrology.Factor
data LCSU star = MkLCSU_ [(star, star)]
| DefaultLCSU
type family Lookup (dim :: *) (lcsu :: LCSU *) :: * where
Lookup dim (MkLCSU_ ('(dim, unit) ': rest)) = unit
Lookup dim (MkLCSU_ ('(other, u) ': rest)) = Lookup dim (MkLCSU_ rest)
Lookup dim DefaultLCSU = DefaultUnitOfDim dim
type family LookupList (keys :: [Factor *]) (map :: LCSU *) :: [Factor *] where
LookupList '[] lcsu = '[]
LookupList (F dim z ': rest) lcsu
= F (Lookup dim lcsu) z ': LookupList rest lcsu
-- | Assign a default unit for a dimension. Necessary only when using
-- default LCSUs.
type family DefaultUnitOfDim (dim :: *) :: *
-- use type family to prevent pattern-matching
-- | Make a local consistent set of units. The argument is a type-level
-- list of tuple types, to be interpreted as an association list from
-- dimensions to units. For example:
--
-- > type MyLCSU = MkLCSU '[(Length, Foot), (Mass, Gram), (Time, Year)]
type family MkLCSU pairs where -- uses unpromoted tuples to make it easier for users
MkLCSU pairs = MkLCSU_ (UsePromotedTuples pairs)
type family UsePromotedTuples pairs where
UsePromotedTuples '[] = '[]
UsePromotedTuples ((dim, unit) ': rest) = ('(dim, unit) ': UsePromotedTuples rest)