1 {-# LANGUAGE DeriveDataTypeable #-}
2 {-# LANGUAGE FlexibleContexts #-}
3 {-# LANGUAGE FlexibleInstances #-}
4 {-# LANGUAGE StandaloneDeriving #-}
5 {-# LANGUAGE TypeFamilies #-}
6 {-# OPTIONS_GHC -fno-warn-orphans #-}
7 module Hcompta.Filter.Amount where
9 import Data.Decimal (Decimal, DecimalRaw(..), roundTo)
10 import Data.Eq (Eq(..))
11 import Data.Maybe (Maybe(..))
12 import Data.Ord (Ord(..))
13 import Data.Text (Text)
14 import qualified Data.Text as Text
15 import Data.Typeable ()
16 import Data.Word (Word8)
17 import Prelude ((.), Integral, Num(..), fromIntegral)
18 import Text.Show (Show(..))
20 import Hcompta.Quantity
21 import qualified Hcompta.Filter as Filter
22 import Hcompta.Polarize
23 import qualified Hcompta.Unit as Unit
26 type Quantity = Decimal
27 deriving instance Data Quantity
29 -- | Round the two 'DecimalRaw' values to the smallest exponent.
30 round_min :: Integral i => DecimalRaw i -> DecimalRaw i -> (Word8, i, i)
31 round_min d1@(Decimal e1 _) d2@(Decimal e2 _) = (e, n1, n2)
34 Decimal _ n1 = roundTo e d1
35 Decimal _ n2 = roundTo e d2
37 instance Zero Quantity where
39 quantity_null = (==) 0
40 instance Addable Quantity where
42 Decimal e (fromIntegral (n1 + n2))
43 where (e, n1, n2) = round_min d1 d2
44 instance Negable Quantity where
46 instance Polarizable Quantity where
47 polarizable_negative q =
51 polarizable_positive q =
59 deriving (Data, Eq, Ord, Show, Typeable)
61 instance Unit.Unit Unit where
62 unit_empty = Unit (Text.pack "")
63 unit_text (Unit t) = t
69 , amount_quantity :: Quantity
70 } deriving (Data, Eq, Show, Typeable)
71 instance Filter.Amount Amount where
72 type Amount_Unit Amount = Unit
73 type Amount_Quantity Amount = Quantity
74 amount_quantity = polarize . amount_quantity
75 amount_unit = amount_unit