mirror of
https://github.com/simonmichael/hledger.git
synced 2024-11-07 21:15:19 +03:00
move types to bottom
This commit is contained in:
parent
224c05aa22
commit
2ddeb4841c
@ -14,11 +14,6 @@ import Ledger
|
||||
|
||||
-- an Account caches an account's name, balance (including sub-accounts)
|
||||
-- and transactions (excluding sub-accounts)
|
||||
data Account = Account {
|
||||
aname :: AccountName,
|
||||
atransactions :: [EntryTransaction],
|
||||
abalance :: Amount
|
||||
}
|
||||
|
||||
instance Show Account where
|
||||
show (Account a ts b) = printf "Account %s with %d transactions" a $ length ts
|
||||
|
@ -5,7 +5,6 @@ import Types
|
||||
|
||||
-- AccountNames are strings like "assets:cash:petty"; from these we build
|
||||
-- the chart of accounts, which should be a simple hierarchy.
|
||||
type AccountName = String
|
||||
|
||||
accountNameComponents :: AccountName -> [String]
|
||||
accountNameComponents = splitAtElement ':'
|
||||
|
45
Amount.hs
45
Amount.hs
@ -2,8 +2,9 @@ module Amount
|
||||
where
|
||||
import Utils
|
||||
import Types
|
||||
import Currency
|
||||
|
||||
{-
|
||||
{-
|
||||
a simple amount is a currency, quantity pair:
|
||||
|
||||
$1
|
||||
@ -40,43 +41,6 @@ tests = runTestTT $ test [
|
||||
parseAmount "$1" ~?= dollars 1 -- currently 0
|
||||
]
|
||||
|
||||
-- currency
|
||||
|
||||
data Currency = Currency {
|
||||
symbol :: String,
|
||||
rate :: Double -- relative to the dollar
|
||||
} deriving (Eq,Show)
|
||||
|
||||
currencies =
|
||||
[
|
||||
Currency "$" 1
|
||||
,Currency "EUR" 0.760383
|
||||
,Currency "£" 0.512527
|
||||
,Currency "h" 60 -- hours
|
||||
,Currency "m" 1 -- minutes
|
||||
]
|
||||
|
||||
getcurrency :: String -> Currency
|
||||
getcurrency s = head $ [(Currency symbol rate) | (Currency symbol rate) <- currencies, symbol==s]
|
||||
|
||||
-- convenience
|
||||
dollars = Amount $ getcurrency "$"
|
||||
euro = Amount $ getcurrency "EUR"
|
||||
pounds = Amount $ getcurrency "£"
|
||||
hours = Amount $ getcurrency "h"
|
||||
minutes = Amount $ getcurrency "m"
|
||||
|
||||
conversionRate :: Currency -> Currency -> Double
|
||||
conversionRate oldc newc = (rate newc) / (rate oldc)
|
||||
|
||||
|
||||
-- amount
|
||||
|
||||
data Amount = Amount {
|
||||
currency :: Currency,
|
||||
quantity :: Double
|
||||
} deriving (Eq)
|
||||
|
||||
instance Show Amount where show = showAmountRoundedOrZero
|
||||
|
||||
nullamt = dollars 0
|
||||
@ -107,8 +71,3 @@ toCurrency :: Currency -> Amount -> Amount
|
||||
toCurrency newc (Amount oldc q) =
|
||||
Amount newc (q * (conversionRate oldc newc))
|
||||
|
||||
|
||||
-- mixed amounts
|
||||
|
||||
--data MixedAmount = MixedAmount [Amount] deriving (Eq,Ord)
|
||||
|
||||
|
27
Currency.hs
Normal file
27
Currency.hs
Normal file
@ -0,0 +1,27 @@
|
||||
module Currency
|
||||
where
|
||||
import Utils
|
||||
import Types
|
||||
|
||||
currencies =
|
||||
[
|
||||
Currency "$" 1
|
||||
,Currency "EUR" 0.760383
|
||||
,Currency "£" 0.512527
|
||||
,Currency "h" 60 -- hours
|
||||
,Currency "m" 1 -- minutes
|
||||
]
|
||||
|
||||
getcurrency :: String -> Currency
|
||||
getcurrency s = head $ [(Currency symbol rate) | (Currency symbol rate) <- currencies, symbol==s]
|
||||
|
||||
conversionRate :: Currency -> Currency -> Double
|
||||
conversionRate oldc newc = (rate newc) / (rate oldc)
|
||||
|
||||
-- convenient amount constructors
|
||||
dollars = Amount $ getcurrency "$"
|
||||
euro = Amount $ getcurrency "EUR"
|
||||
pounds = Amount $ getcurrency "£"
|
||||
hours = Amount $ getcurrency "h"
|
||||
minutes = Amount $ getcurrency "m"
|
||||
|
20
Entry.hs
20
Entry.hs
@ -6,8 +6,6 @@ import Types
|
||||
import Transaction
|
||||
|
||||
|
||||
type EntryStatus = Bool
|
||||
|
||||
-- a register entry is displayed as two or more lines like this:
|
||||
-- date description account amount balance
|
||||
-- DDDDDDDDDD dddddddddddddddddddd aaaaaaaaaaaaaaaaaaaaaa AAAAAAAAAAA AAAAAAAAAAAA
|
||||
@ -19,14 +17,6 @@ type EntryStatus = Bool
|
||||
-- amtWidth = 11
|
||||
-- balWidth = 12
|
||||
|
||||
data Entry = Entry {
|
||||
edate :: Date,
|
||||
estatus :: EntryStatus,
|
||||
ecode :: String,
|
||||
edescription :: String,
|
||||
etransactions :: [Transaction]
|
||||
} deriving (Eq)
|
||||
|
||||
instance Show Entry where show = showEntry
|
||||
|
||||
showEntry e = (showDate $ edate e) ++ " " ++ (showDescription $ edescription e) ++ " "
|
||||
@ -43,19 +33,9 @@ autofillEntry e =
|
||||
|
||||
-- modifier & periodic entries
|
||||
|
||||
data ModifierEntry = ModifierEntry { -- aka "automated entry"
|
||||
valueexpr :: String,
|
||||
m_transactions :: [Transaction]
|
||||
} deriving (Eq)
|
||||
|
||||
instance Show ModifierEntry where
|
||||
show e = "= " ++ (valueexpr e) ++ "\n" ++ unlines (map show (m_transactions e))
|
||||
|
||||
data PeriodicEntry = PeriodicEntry {
|
||||
periodexpr :: String,
|
||||
p_transactions :: [Transaction]
|
||||
} deriving (Eq)
|
||||
|
||||
instance Show PeriodicEntry where
|
||||
show e = "~ " ++ (periodexpr e) ++ "\n" ++ unlines (map show (p_transactions e))
|
||||
|
||||
|
@ -6,6 +6,7 @@ import Types
|
||||
import Entry
|
||||
import Transaction
|
||||
import Amount
|
||||
import Currency
|
||||
|
||||
|
||||
-- We convert Transactions into EntryTransactions, which are (entry,
|
||||
@ -13,8 +14,6 @@ import Amount
|
||||
-- reference their entry like in OO. These are referred to as just
|
||||
-- "transactions" in code above.
|
||||
|
||||
type EntryTransaction = (Entry,Transaction)
|
||||
|
||||
entry (e,t) = e
|
||||
transaction (e,t) = t
|
||||
date (e,t) = edate e
|
||||
|
@ -9,12 +9,6 @@ import Entry
|
||||
import EntryTransaction
|
||||
|
||||
|
||||
data Ledger = Ledger {
|
||||
modifier_entries :: [ModifierEntry],
|
||||
periodic_entries :: [PeriodicEntry],
|
||||
entries :: [Entry]
|
||||
} deriving (Eq)
|
||||
|
||||
instance Show Ledger where
|
||||
show l = printf "Ledger with %d entries"
|
||||
((length $ entries l) +
|
||||
|
2
Makefile
2
Makefile
@ -22,7 +22,7 @@ haddock:
|
||||
haddock -h -o doc *.hs
|
||||
|
||||
overview:
|
||||
@./overview.hs hledger.hs
|
||||
@./overview.hs Types.hs
|
||||
|
||||
loc:
|
||||
@darcs trackdown 'find . -name "*hs" |xargs wc -l |echo OUTPUT `tail -1`; false' |ruby -nae'puts $$F[1] if /^OUTPUT/'
|
||||
|
@ -1,6 +1,7 @@
|
||||
-- data types & behaviours
|
||||
-- all data types & behaviours
|
||||
module Models (
|
||||
module Types,
|
||||
module Currency,
|
||||
module Amount,
|
||||
module AccountName,
|
||||
module Transaction,
|
||||
@ -14,6 +15,7 @@ where
|
||||
import qualified Data.Map as Map
|
||||
|
||||
import Types
|
||||
import Currency
|
||||
import Amount
|
||||
import AccountName
|
||||
import Transaction
|
||||
|
11
TimeLog.hs
11
TimeLog.hs
@ -2,24 +2,15 @@ module TimeLog
|
||||
where
|
||||
import Utils
|
||||
import Types
|
||||
import Currency
|
||||
import Amount
|
||||
import Transaction
|
||||
import Entry
|
||||
import Ledger
|
||||
|
||||
data TimeLogEntry = TimeLogEntry {
|
||||
tcode :: Char,
|
||||
tdatetime :: DateTime,
|
||||
tcomment :: String
|
||||
} deriving (Eq,Ord)
|
||||
|
||||
instance Show TimeLogEntry where
|
||||
show t = printf "%s %s %s" (show $ tcode t) (tdatetime t) (tcomment t)
|
||||
|
||||
data TimeLog = TimeLog {
|
||||
timelog_entries :: [TimeLogEntry]
|
||||
} deriving (Eq)
|
||||
|
||||
instance Show TimeLog where
|
||||
show tl = printf "TimeLog with %d entries" $ length $ timelog_entries tl
|
||||
|
||||
|
@ -7,11 +7,6 @@ import AccountName
|
||||
import Amount
|
||||
|
||||
|
||||
data Transaction = Transaction {
|
||||
taccount :: AccountName,
|
||||
tamount :: Amount
|
||||
} deriving (Eq)
|
||||
|
||||
instance Show Transaction where show = showTransaction
|
||||
|
||||
showTransaction t = (showAccountName $ taccount t) ++ " " ++ (showAmount $ tamount t)
|
||||
|
115
Types.hs
115
Types.hs
@ -2,6 +2,121 @@ module Types
|
||||
where
|
||||
import Utils
|
||||
|
||||
{-
|
||||
|
||||
First, here is the module hierarchy. The initial implementation defined
|
||||
types in each module and so was strictly layered. Now, all types have been
|
||||
moved to the bottom, with modules still used to group related functions
|
||||
(aka methods - "make overview" to list these).
|
||||
|
||||
hledger
|
||||
Options
|
||||
Tests
|
||||
Parse
|
||||
Models
|
||||
TimeLog
|
||||
TimeLogEntry
|
||||
Account
|
||||
Ledger
|
||||
EntryTransaction
|
||||
Entry
|
||||
Transaction
|
||||
AccountName
|
||||
Amount
|
||||
Currency
|
||||
Types
|
||||
Utils
|
||||
|
||||
(Will this allow a more muddled design ? Possibly, though starting out
|
||||
layered probably helped, but note previous comment:
|
||||
|
||||
Each layer can only reference things below it. A seeming problem:
|
||||
CookedLedger must be at the top so it can cache any of the others. Code
|
||||
below it can not use its fast functions, and code above it should use
|
||||
only its functions for good performance. Upper-level code loses the
|
||||
benefit of many lower-level functions and has to reimplement them as
|
||||
fast versions.)
|
||||
|
||||
-}
|
||||
|
||||
type Date = String
|
||||
|
||||
type DateTime = String
|
||||
|
||||
data Currency = Currency {
|
||||
symbol :: String,
|
||||
rate :: Double -- relative to the dollar
|
||||
} deriving (Eq,Show)
|
||||
|
||||
-- some amount of money, time, stock, oranges, etc.
|
||||
data Amount = Amount {
|
||||
currency :: Currency,
|
||||
quantity :: Double
|
||||
} deriving (Eq)
|
||||
|
||||
-- AccountNames are strings like "assets:cash:petty"; from these we build
|
||||
-- the chart of accounts, which should be a simple hierarchy.
|
||||
type AccountName = String
|
||||
|
||||
-- a flow of an amount to an account
|
||||
data Transaction = Transaction {
|
||||
taccount :: AccountName,
|
||||
tamount :: Amount
|
||||
} deriving (Eq)
|
||||
|
||||
-- cleared ?
|
||||
type EntryStatus = Bool
|
||||
|
||||
-- a ledger entry, with two or more balanced transactions
|
||||
data Entry = Entry {
|
||||
edate :: Date,
|
||||
estatus :: EntryStatus,
|
||||
ecode :: String,
|
||||
edescription :: String,
|
||||
etransactions :: [Transaction]
|
||||
} deriving (Eq)
|
||||
|
||||
-- an "automated" entry (see = in ledger manual)
|
||||
data ModifierEntry = ModifierEntry {
|
||||
valueexpr :: String,
|
||||
m_transactions :: [Transaction]
|
||||
} deriving (Eq)
|
||||
|
||||
-- a periodic entry (see ~ in ledger manual)
|
||||
data PeriodicEntry = PeriodicEntry {
|
||||
periodexpr :: String,
|
||||
p_transactions :: [Transaction]
|
||||
} deriving (Eq)
|
||||
|
||||
-- a parsed ledger file
|
||||
data Ledger = Ledger {
|
||||
modifier_entries :: [ModifierEntry],
|
||||
periodic_entries :: [PeriodicEntry],
|
||||
entries :: [Entry]
|
||||
} deriving (Eq)
|
||||
|
||||
-- we also process timeclock.el's timelogs
|
||||
data TimeLogEntry = TimeLogEntry {
|
||||
tcode :: Char,
|
||||
tdatetime :: DateTime,
|
||||
tcomment :: String
|
||||
} deriving (Eq,Ord)
|
||||
|
||||
data TimeLog = TimeLog {
|
||||
timelog_entries :: [TimeLogEntry]
|
||||
} deriving (Eq)
|
||||
|
||||
-- We convert Transactions into EntryTransactions, which are (entry,
|
||||
-- transaction) pairs, since I couldn't see how to have transactions
|
||||
-- reference their entry like in OO. These are referred to as just
|
||||
-- "transactions" in modules above EntryTransaction.
|
||||
type EntryTransaction = (Entry,Transaction)
|
||||
|
||||
-- an Account caches a particular account's name, balance and transactions
|
||||
-- from a Ledger
|
||||
data Account = Account {
|
||||
aname :: AccountName,
|
||||
atransactions :: [EntryTransaction], -- excludes sub-accounts
|
||||
abalance :: Amount -- includes sub-accounts
|
||||
}
|
||||
|
||||
|
13
Utils.hs
13
Utils.hs
@ -26,9 +26,6 @@ splitAtElement e l =
|
||||
where
|
||||
(first,rest) = break (e==) l'
|
||||
|
||||
-- testing support
|
||||
|
||||
|
||||
-- tree tools
|
||||
|
||||
root = rootLabel
|
||||
@ -37,8 +34,7 @@ branches = subForest
|
||||
-- remove all nodes past a certain depth
|
||||
treeprune :: Int -> Tree a -> Tree a
|
||||
treeprune 0 t = Node (root t) []
|
||||
treeprune d t =
|
||||
Node (root t) (map (treeprune $ d-1) $ branches t)
|
||||
treeprune d t = Node (root t) (map (treeprune $ d-1) $ branches t)
|
||||
|
||||
-- apply f to all tree nodes
|
||||
treemap :: (a -> b) -> Tree a -> Tree b
|
||||
@ -57,4 +53,9 @@ treeany f t = (f $ root t) || (any (treeany f) $ branches t)
|
||||
-- treedrop -- remove the leaves which do fulfill predicate.
|
||||
-- treedropall -- do this repeatedly.
|
||||
|
||||
strace a = trace (show a) a
|
||||
-- debugging
|
||||
|
||||
strace a = trace (show a) a
|
||||
|
||||
-- testing
|
||||
|
||||
|
20
hledger.hs
20
hledger.hs
@ -4,25 +4,7 @@ hledger - ledger-compatible money management tool (& haskell study)
|
||||
GPLv3, (c) Simon Michael & contributors
|
||||
A port of John Wiegley's ledger at http://newartisans.com/ledger.html
|
||||
|
||||
Here is a rough overview of the module/model hierarchy:
|
||||
|
||||
hledger
|
||||
Options
|
||||
Tests
|
||||
Parse
|
||||
Models
|
||||
TimeLog
|
||||
TimeLogEntry
|
||||
Account
|
||||
Ledger
|
||||
EntryTransaction
|
||||
Entry
|
||||
Transaction
|
||||
AccountName
|
||||
Amount
|
||||
Types
|
||||
Utils
|
||||
|
||||
See Types.hs for a code overview.
|
||||
-}
|
||||
|
||||
module Main
|
||||
|
Loading…
Reference in New Issue
Block a user