{-# LANGUAGE BangPatterns #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Hcompta.Journal where import Data.Map.Strict (Map) import qualified Data.Map.Strict as Data.Map import Hcompta.Date (Date) import Hcompta.Lib.Consable (Consable(..)) class Transaction t where transaction_date :: t -> Date newtype Journal t = Journal (Map Date [t]) deriving (Eq, Show) instance Foldable Journal where foldMap f (Journal t) = foldMap (foldMap f) t instance Transaction t => Monoid (Journal t) where mempty = Journal mempty mappend (Journal x) (Journal y) = Journal $ Data.Map.unionWith (flip mappend) x y instance Transaction t => Consable () (Journal) t where mcons () = cons instance Consable () [] transaction where mcons () t !j = (:) t j -- | Return the given 'Journal' -- updated by the given 'Transaction'. -- -- NOTE: to reduce memory consumption when 'cons'ing iteratively, -- the given 'Journal' is matched strictly. cons :: Transaction t => t -> Journal t -> Journal t cons t (Journal !ts) = Journal $ Data.Map.insertWith (flip mappend) (transaction_date t) [t] ts transactions :: Transaction t => Journal t -> Map Date [t] transactions (Journal ts) = ts