1 {-# LANGUAGE DeriveDataTypeable #-}
2 {-# LANGUAGE FlexibleContexts #-}
3 {-# LANGUAGE FlexibleInstances #-}
4 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
5 {-# LANGUAGE MultiParamTypeClasses #-}
6 {-# LANGUAGE StandaloneDeriving #-}
7 {-# LANGUAGE TypeFamilies #-}
8 module Hcompta.Account where
10 import Control.DeepSeq (NFData)
13 import qualified Data.Foldable
14 import Data.List.NonEmpty (NonEmpty(..))
15 import qualified Data.List.NonEmpty as NonEmpty
16 import Data.Maybe (Maybe(..))
17 import Data.Monoid (Monoid(..))
19 import Prelude (($), (.), Integer, Num(..), const, id)
20 import Text.Show (Show(..))
22 import Hcompta.Anchor (Anchor, Anchors)
23 import qualified Hcompta.Anchor as Anchor
24 import Hcompta.Lib.Consable (Consable(..))
25 import Hcompta.Tag (Tag, Tags)
26 import qualified Hcompta.Tag as Tag
27 import qualified Hcompta.Lib.NonEmpty as NonEmpty
34 , Data (Account_Section a)
35 , NFData (Account_Section a)
36 , Ord (Account_Section a)
37 , Show (Account_Section a)
40 type Account_Section a
41 account_path :: a -> Account_Path (Account_Section a)
42 type Account_Path = NonEmpty
43 instance (Data s, NFData s, Ord s, Show s) => Account (NonEmpty s) where
44 type Account_Section (NonEmpty s) = s
47 -- | Return the 'Account' formed by the given 'Account_Section' and 'Account_Section's.
48 path :: section -> [section] -> Account_Path section
51 -- | Return the number of 'Account_Section's in the given 'Account_Path'.
52 depth :: Account a => a -> Integer
53 depth = Data.Foldable.foldl' (\d -> const $ d + 1) 0 . account_path
55 -- | Return the given 'Account' without its last 'Account_Section' if any.
56 ascending :: Account_Path a -> Maybe (Account_Path a)
57 ascending = NonEmpty.ascending
59 -- | Apply the given function to all the prefixes
60 -- of the given 'Account_Path' (including itself).
61 foldr :: Account_Path s -> (Account_Path s -> a -> a) -> a -> a
62 foldr (n0:|n0s) = go [] n0s
64 go s [] f acc = f (n0:|s) acc
66 go (s `mappend` [n]) ns f (f (n0:|s) acc)
68 -- | Return an 'Account_Path' from the given list.
69 from_List :: [s] -> Account_Path s
70 from_List = NonEmpty.fromList
72 -- * Type 'Account_Anchor'
73 newtype Account_Anchor
74 = Account_Anchor Anchor
75 deriving (Data, Eq, NFData, Ord, Show, Typeable)
76 newtype Account_Anchors
77 = Account_Anchors Anchors
78 deriving (Data, Eq, Monoid, NFData, Show, Typeable)
80 instance Consable Anchor Account_Anchors where
81 mcons a (Account_Anchors anchors) =
82 Account_Anchors $ mcons a anchors
84 anchor :: Anchor.Path -> Account_Anchor
85 anchor = Account_Anchor . Anchor.anchor
87 -- | Return the given 'Account_Anchors' with the given 'Account_Anchor' incorporated.
88 anchor_cons :: Account_Anchor -> Account_Anchors -> Account_Anchors
89 anchor_cons (Account_Anchor t) (Account_Anchors ts) =
90 Account_Anchors $ Anchor.cons t ts
92 -- * Type 'Account_Tag'
95 deriving (Data, Eq, NFData, Ord, Show, Typeable)
98 deriving (Data, Eq, Monoid, NFData, Show, Typeable)
100 instance Consable Tag Account_Tags where
101 mcons t (Account_Tags tags) =
102 Account_Tags $ mcons t tags
104 tag :: Tag.Path -> Tag.Value -> Account_Tag
105 tag p v = Account_Tag $ Tag.tag p v
107 -- | Return the given 'Account_Tags' with the given 'Account_Tag' incorporated.
108 tag_cons :: Account_Tag -> Account_Tags -> Account_Tags
109 tag_cons (Account_Tag t) (Account_Tags ts) =
110 Account_Tags $ Tag.cons t ts