From 7ece827d45a3025c7a5a629918f7a10ce35120b9 Mon Sep 17 00:00:00 2001 From: Johannes Lund Date: Tue, 7 May 2019 11:57:42 +0200 Subject: [PATCH 1/3] Rewrite Quantity documentation --- lib/core/src/Data/Quantity.hs | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/core/src/Data/Quantity.hs b/lib/core/src/Data/Quantity.hs index f246c9f81fe..83b7fa344db 100644 --- a/lib/core/src/Data/Quantity.hs +++ b/lib/core/src/Data/Quantity.hs @@ -52,18 +52,32 @@ import GHC.TypeLits import qualified Data.Text as T --- | Represents a value that has an associated unit of measure, based on some --- underlying type. +-- | @Quantity (u :: Symbol) a@ is a primitive @a@ multiplied by an unit @u@. -- --- >>> newtype Amount = Amount (Quantity "lovelace" Word32) +-- Example: +-- +-- Instead of providing the unit implicitly as a comment, or a part of a name +-- +-- >>> a :: Word32 -- in lovelace +-- +-- we can write +-- +-- >>> a :: Quantity "lovelace" Word32 +-- +-- which now has a different type from +-- +-- >>> b :: Quantity "lovelace/byte" Word32 +-- +-- so mixing them up is more difficult. +-- +-- The unit is mostly a phantom type, but it is also included in the +-- @ToJSON@/@FromJSON@ instances. newtype Quantity (u :: Symbol) a = Quantity a deriving stock (Generic, Show, Eq, Ord) deriving newtype (Bounded, Enum) instance NFData a => NFData (Quantity u a) --- | Encode to JSON delegating the --- -- >>> Aeson.encode $ Quantity @"lovelace" 14 -- {"unit":"lovelace","quantity":14} instance (KnownSymbol u, ToJSON a) => ToJSON (Quantity u a) where From b870798a72c5518e4f82659996d3a2b0489c6959 Mon Sep 17 00:00:00 2001 From: Johannes Lund Date: Tue, 7 May 2019 12:08:54 +0200 Subject: [PATCH 2/3] Rename `u` to `unit` --- lib/core/src/Data/Quantity.hs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/core/src/Data/Quantity.hs b/lib/core/src/Data/Quantity.hs index 83b7fa344db..79de53091c9 100644 --- a/lib/core/src/Data/Quantity.hs +++ b/lib/core/src/Data/Quantity.hs @@ -52,7 +52,7 @@ import GHC.TypeLits import qualified Data.Text as T --- | @Quantity (u :: Symbol) a@ is a primitive @a@ multiplied by an unit @u@. +-- | @Quantity (unit :: Symbol) a@ is a primitive @a@ multiplied by an @unit@. -- -- Example: -- @@ -72,26 +72,26 @@ import qualified Data.Text as T -- -- The unit is mostly a phantom type, but it is also included in the -- @ToJSON@/@FromJSON@ instances. -newtype Quantity (u :: Symbol) a = Quantity a +newtype Quantity (unit :: Symbol) a = Quantity a deriving stock (Generic, Show, Eq, Ord) deriving newtype (Bounded, Enum) -instance NFData a => NFData (Quantity u a) +instance NFData a => NFData (Quantity unit a) -- >>> Aeson.encode $ Quantity @"lovelace" 14 -- {"unit":"lovelace","quantity":14} -instance (KnownSymbol u, ToJSON a) => ToJSON (Quantity u a) where +instance (KnownSymbol unit, ToJSON a) => ToJSON (Quantity unit a) where toJSON (Quantity a) = object - [ "unit" .= symbolVal (Proxy :: Proxy u) + [ "unit" .= symbolVal (Proxy :: Proxy unit) , "quantity" .= toJSON a ] -instance (KnownSymbol u, FromJSON a) => FromJSON (Quantity u a) where +instance (KnownSymbol unit, FromJSON a) => FromJSON (Quantity unit a) where parseJSON = withObject "Quantity" $ \o -> do - verifyUnit (Proxy :: Proxy u) =<< o .: "unit" + verifyUnit (Proxy :: Proxy unit) =<< o .: "unit" Quantity <$> o .: "quantity" where - verifyUnit :: Proxy (u :: Symbol) -> Value -> Parser () + verifyUnit :: Proxy (unit :: Symbol) -> Value -> Parser () verifyUnit proxy = \case String u' | u' == T.pack u -> pure () _ -> fail $ From 2390a8d58e02b4462157187d3d94dcb2828b3048 Mon Sep 17 00:00:00 2001 From: Johannes Lund Date: Tue, 7 May 2019 12:27:36 +0200 Subject: [PATCH 3/3] Move ToJSON comment --- lib/core/src/Data/Quantity.hs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/core/src/Data/Quantity.hs b/lib/core/src/Data/Quantity.hs index 79de53091c9..46242635f6f 100644 --- a/lib/core/src/Data/Quantity.hs +++ b/lib/core/src/Data/Quantity.hs @@ -72,14 +72,15 @@ import qualified Data.Text as T -- -- The unit is mostly a phantom type, but it is also included in the -- @ToJSON@/@FromJSON@ instances. +-- +-- >>> Aeson.encode $ Quantity @"lovelace" 14 +-- {"unit":"lovelace","quantity":14} newtype Quantity (unit :: Symbol) a = Quantity a deriving stock (Generic, Show, Eq, Ord) deriving newtype (Bounded, Enum) instance NFData a => NFData (Quantity unit a) --- >>> Aeson.encode $ Quantity @"lovelace" 14 --- {"unit":"lovelace","quantity":14} instance (KnownSymbol unit, ToJSON a) => ToJSON (Quantity unit a) where toJSON (Quantity a) = object [ "unit" .= symbolVal (Proxy :: Proxy unit)