|
| 1 | +{-# LANGUAGE DefaultSignatures #-} |
| 2 | +{-# LANGUAGE TypeFamilyDependencies #-} |
| 3 | +module Money.Theory.MonetaryTypes where |
| 4 | +-- base |
| 5 | +import Data.Kind (Type) |
| 6 | + |
| 7 | + |
| 8 | +-- | Type system trite: types used in semantic money |
| 9 | +-- |
| 10 | +-- Note: |
| 11 | +-- * Index related types through associated type families. |
| 12 | +-- * Use type family dependencies to make these types to the index type injective. |
| 13 | +class ( Eq (MT_TIME mt), Ord (MT_TIME mt), Num (MT_TIME mt) |
| 14 | + , Eq (MT_VALUE mt), Ord (MT_VALUE mt), Num (MT_VALUE mt) |
| 15 | + , Eq (MT_UNIT mt), Ord (MT_UNIT mt), Num (MT_UNIT mt) |
| 16 | + ) => |
| 17 | + MonetaryTypes mt where |
| 18 | + mt_v_mul_t :: MT_VALUE mt -> MT_TIME mt -> MT_VALUE mt |
| 19 | + default mt_v_mul_t :: |
| 20 | + Integral (MT_TIME mt) => |
| 21 | + MT_VALUE mt -> MT_TIME mt -> MT_VALUE mt |
| 22 | + mt_v_mul_t v t = v * (fromInteger . toInteger) t |
| 23 | + |
| 24 | + mt_v_mul_u :: MT_VALUE mt -> MT_UNIT mt -> MT_VALUE mt |
| 25 | + default mt_v_mul_u :: |
| 26 | + Integral (MT_UNIT mt) => |
| 27 | + MT_VALUE mt -> MT_UNIT mt -> MT_VALUE mt |
| 28 | + mt_v_mul_u v u = v * (fromInteger . toInteger) u |
| 29 | + |
| 30 | + mt_v_div_u :: MT_VALUE mt -> MT_UNIT mt -> MT_VALUE mt |
| 31 | + default mt_v_div_u :: |
| 32 | + (Integral (MT_VALUE mt), Integral (MT_UNIT mt)) => |
| 33 | + MT_VALUE mt -> MT_UNIT mt -> MT_VALUE mt |
| 34 | + mt_v_div_u v u = let u' = (fromInteger . toInteger) u in v `div` u' |
| 35 | + |
| 36 | + mt_v_mul_u_qr_u :: MT_VALUE mt -> (MT_UNIT mt, MT_UNIT mt) -> (MT_VALUE mt, MT_VALUE mt) |
| 37 | + default mt_v_mul_u_qr_u :: |
| 38 | + (Integral (MT_VALUE mt), Integral (MT_UNIT mt)) => |
| 39 | + MT_VALUE mt -> (MT_UNIT mt, MT_UNIT mt) -> (MT_VALUE mt, MT_VALUE mt) |
| 40 | + mt_v_mul_u_qr_u v (u1, u2) = (v * (fromInteger . toInteger) u1) `quotRem` (fromInteger . toInteger) u2 |
| 41 | + |
| 42 | + type family MT_TIME mt = (t :: Type) | t -> mt |
| 43 | + type family MT_VALUE mt = (v :: Type) | v -> mt |
| 44 | + type family MT_UNIT mt = (u :: Type) | u -> mt |
| 45 | + -- TODO: Do we need FlowRate type? |
0 commit comments