1 {-# LANGUAGE DeriveAnyClass #-}
3 module Literate.Accounting.Flow where
5 import Literate.Accounting.Quantity
6 import Literate.Prelude
10 -- | A 'Flow keeps track separatly of what 'FlowOrigin'
11 -- and what 'FlowTarget' of an account.
16 deriving (Eq, Show, Generic, NFData, Functor)
18 instance FromRational qty => FromRational (Flow qty) where
20 | i <= 0 = FlowTarget (fromRational i)
21 | otherwise = FlowOrigin (fromRational i)
22 instance FromInteger qty => FromInteger (Flow qty) where
24 | i <= 0 = FlowTarget (fromInteger i)
25 | otherwise = FlowOrigin (fromInteger i)
26 instance (Zeroable a, Addable a) => Zeroable (Flow a) where
27 zero = FlowOrigin zero
29 FlowOrigin i -> isZero i
30 FlowTarget o -> isZero o
31 FlowBidir o i -> isZero (o + i)
32 instance Addable a => Addable (Flow a) where
33 FlowOrigin i + FlowTarget o = FlowBidir o i
34 FlowOrigin ix + FlowOrigin py = FlowOrigin (ix + py)
35 FlowOrigin i + FlowBidir ny py = FlowBidir ny (i + py)
36 FlowTarget ox + FlowTarget ny = FlowTarget (ox + ny)
37 FlowTarget o + FlowOrigin i = FlowBidir o i
38 FlowTarget ox + FlowBidir ny i = FlowBidir (ox + ny) i
39 FlowBidir ox ix + FlowTarget o = FlowBidir (ox + o) ix
40 FlowBidir ox ix + FlowOrigin py = FlowBidir ox (ix + py)
41 FlowBidir ox ix + FlowBidir ny py = FlowBidir (ox + ny) (ix + py)
42 instance Flowable (Flow a) where
44 FlowOrigin _ -> Nothing
45 FlowTarget _ -> Just f
46 FlowBidir n _ -> Just (FlowTarget n)
48 FlowOrigin _ -> Just f
49 FlowTarget _ -> Nothing
50 FlowBidir _ p -> Just (FlowOrigin p)
52 flowOrigin :: Flow a -> Maybe a
54 FlowOrigin i -> Just i
55 FlowTarget _ -> Nothing
56 FlowBidir _ i -> Just i
58 flowTarget :: Flow a -> Maybe a
60 FlowOrigin _ -> Nothing
61 FlowTarget o -> Just o
62 FlowBidir o _ -> Just o
64 flow :: Flowable a => a -> Flow a
66 case (outOf f, inOf f) of
67 (Just o, Nothing) -> FlowTarget o
68 (Nothing, Just i) -> FlowOrigin i
69 (Just o, Just i) -> FlowBidir o i
70 (Nothing, Nothing) -> FlowBidir f f
71 unFlow :: Addable a => Flow a -> a
75 FlowBidir o i -> o + i
78 class Flowable a where
83 instance Flowable Decimal where
92 instance Flowable a => Flowable (Map k a) where
94 case Map.mapMaybe inOf q of
95 m | Map.null m -> Nothing
98 case Map.mapMaybe outOf q of
99 m | Map.null m -> Nothing
101 instance Flowable a => Flowable (k, a) where
102 inOf (u, q) = (u,) <$> inOf q
103 outOf (u, q) = (u,) <$> outOf q