1 {-# LANGUAGE DeriveAnyClass #-}
3 module Literate.Accounting.Flow where
7 import Data.Functor (Functor)
8 import Data.Maybe (Maybe (..))
9 import Data.Ord (Ord (..))
10 import GHC.Generics (Generic)
11 import Text.Show (Show (..))
13 import Literate.Accounting.Quantity
14 import Literate.Prelude
18 -- | A 'Flow keeps track separatly of what 'FlowSource'
19 -- and what 'FlowDest' of an account.
24 deriving (Eq, Show, Generic, NFData, Functor)
26 instance FromRational qty => FromRational (Flow qty) where
28 | i <= 0 = FlowDest (fromRational i)
29 | otherwise = FlowSource (fromRational i)
30 instance FromInteger qty => FromInteger (Flow qty) where
32 | i <= 0 = FlowDest (fromInteger i)
33 | otherwise = FlowSource (fromInteger i)
34 instance (Zeroable a, Addable a) => Zeroable (Flow a) where
35 zero = FlowSource zero
37 FlowDest o -> isZero o
38 FlowSource i -> isZero i
39 FlowBidir o i -> isZero (o + i)
40 instance Addable a => Addable (Flow a) where
41 FlowSource i + FlowDest o = FlowBidir o i
42 FlowSource ix + FlowSource py = FlowSource (ix + py)
43 FlowSource i + FlowBidir ny py = FlowBidir ny (i + py)
44 FlowDest ox + FlowDest ny = FlowDest (ox + ny)
45 FlowDest o + FlowSource i = FlowBidir o i
46 FlowDest ox + FlowBidir ny i = FlowBidir (ox + ny) i
47 FlowBidir ox ix + FlowDest o = FlowBidir (ox + o) ix
48 FlowBidir ox ix + FlowSource py = FlowBidir ox (ix + py)
49 FlowBidir ox ix + FlowBidir ny py = FlowBidir (ox + ny) (ix + py)
50 instance Flowable (Flow a) where
52 FlowSource _ -> Nothing
54 FlowBidir n _ -> Just (FlowDest n)
56 FlowSource _ -> Just f
58 FlowBidir _ p -> Just (FlowSource p)
60 flowIn :: Flow a -> Maybe a
62 FlowSource i -> Just i
64 FlowBidir _ i -> Just i
66 flowOut :: Flow a -> Maybe a
68 FlowSource _ -> Nothing
70 FlowBidir o _ -> Just o
72 flow :: Flowable a => a -> Flow a
74 case (outOf f, inOf f) of
75 (Just o, Nothing) -> FlowDest o
76 (Nothing, Just i) -> FlowSource i
77 (Just o, Just i) -> FlowBidir o i
78 (Nothing, Nothing) -> FlowBidir f f
79 unFlow :: Addable a => Flow a -> a
83 FlowBidir o i -> o + i
86 class Flowable a where
91 instance Flowable Decimal where
100 instance Flowable a => Flowable (Map k a) where
102 case Map.mapMaybe inOf q of
103 m | Map.null m -> Nothing
106 case Map.mapMaybe outOf q of
107 m | Map.null m -> Nothing
109 instance Flowable a => Flowable (k, a) where
110 inOf (u, q) = (u,) <$> inOf q
111 outOf (u, q) = (u,) <$> outOf q