| Copyright | © 2018 Phil de Joux © 2018 Block Scope Limited |
|---|---|
| License | MPL-2.0 |
| Maintainer | Phil de Joux <phil.dejoux@blockscope.com> |
| Stability | experimental |
| Safe Haskell | None |
| Language | Haskell2010 |
Data.Via.UnitsOfMeasure
Contents
Description
For encoding and decoding newtype quantities as scientific with a fixed number of decimal places and with units.
Usage
With these unit definitons;
[u| m |] [u| km = 1000 m |]
Let's say we have distances in kilometres we'd like encoded with 3 decimal places.
>>>:{newtype Distance a = Distance a deriving (Eq, Ord, Show) instance (q ~ Quantity Double [u| km |]) => DefaultDecimalPlaces (Distance q) where defdp _ = DecimalPlaces 3 instance (q ~ Quantity Double [u| km |]) => Newtype (Distance q) q where pack = Distance unpack (Distance a) = a :}
Encoding and decoding JSON.
>>>:{instance (q ~ Quantity Double [u| km |]) => ToJSON (Distance q) where toJSON x = toJSON $ ViaQ x instance (q ~ Quantity Double [u| km |]) => FromJSON (Distance q) where parseJSON o = do ViaQ x <- parseJSON o; return x :}
>>>[u| 112233.445566 km |][u| 112233.445566 km |]>>>encode (Distance [u| 112233.445566 km |])"\"112233.446 km\"">>>let Just x :: Maybe (Distance (Quantity Double [u| km |])) = decode (encode (Distance [u| 112233.445566 km |])) in xDistance [u| 112233.446 km |]
Similarly for CSV.
>>>:{instance (q ~ Quantity Double [u| km |]) => ToField (Distance q) where toField x = toField $ ViaQ x instance (q ~ Quantity Double [u| km |]) => FromField (Distance q) where parseField c = do ViaQ x <- parseField c; return x :}
>>>let d = Distance [u| 112233.445566 km |]>>>Csv.encode [("A", d)]"A,112233.446 km\r\n">>>Csv.decode NoHeader (Csv.encode [("B", d)]) == Right (fromList [("B", d)])False>>>Csv.decode NoHeader (Csv.encode [("C", d)]) == Right (fromList [("C", Distance [u| 112233.446 km |])])True
Decimal Places and Units
data ViaQ n a u where Source #
An intermediate type used during encoding to JSON with aeson and during
encoding to CSV with cassava. It's also used during decoding.
The original type, a newtype Quantity, goes to and fro via this
quantity so that the rational value can be encoded as a scientific value
with a fixed number of decimal places and with units.
Constructors
| ViaQ :: (DefaultDecimalPlaces n, Newtype n (Quantity a u)) => n -> ViaQ n a u |
Instances
| (DefaultDecimalPlaces n, Newtype n (Quantity a u), Real a, KnownUnit (Unpack u)) => ToJSON (ViaQ n a u) Source # | |
| (DefaultDecimalPlaces n, Newtype n (Quantity a u), Real a, Fractional a, KnownUnit (Unpack u)) => FromJSON (ViaQ n a u) Source # | |
| (DefaultDecimalPlaces n, Newtype n (Quantity a u), Real a, Fractional a, KnownUnit (Unpack u)) => FromField (ViaQ n a u) Source # | |
| (DefaultDecimalPlaces n, Newtype n (Quantity a u), Real a, KnownUnit (Unpack u)) => ToField (ViaQ n a u) Source # | |