h$ieT      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~   None) %(-./0235678;<=>?haspara!Type encoding of a currency pair.1 values are constructed via the data constructor:CurrencyPair "EUR" "USD"EUR/USD and  instances are provided as well:Aeson.decode "{\"base\": \"EUR\", \"quote\": \"EUR\"}" :: Maybe CurrencyPair Just EUR/EUR'Aeson.encode (CurrencyPair "EUR" "USD")&"{\"base\":\"EUR\",\"quote\":\"USD\"}"haspara Base currency+ of the currency pair. Also referred to as counter currency.hasparaQuote currency+ of the currency pair. Also referred to as transaction currency.haspara:Type encoding for currency symbol values with a syntax of [A-Z]{3}[A-Z]*. values can be constructed via  that works in   context:/mkCurrencyError "EUR" :: Either T.Text Currency Right EUR ... or via  that works in  context:&mkCurrencyFail "EUR" :: Maybe CurrencyJust EURAn = instance is provided as well which is unsafe but convenient:"EUR" :: CurrencyEURhasparaSmart constructor for  values within  context.,mkCurrencyError "" :: Either T.Text CurrencyLeft "Currency code error! Expecting at least 3 uppercase ASCII letters, but received: "-mkCurrencyError " " :: Either T.Text CurrencyLeft "Currency code error! Expecting at least 3 uppercase ASCII letters, but received: ".mkCurrencyError "AB" :: Either T.Text CurrencyLeft "Currency code error! Expecting at least 3 uppercase ASCII letters, but received: AB"1mkCurrencyError " ABC " :: Either T.Text CurrencyLeft "Currency code error! Expecting at least 3 uppercase ASCII letters, but received: ABC "/mkCurrencyError "ABC" :: Either T.Text Currency Right ABChasparaSmart constructor for  values within  context.#mkCurrencyFail "" :: Maybe CurrencyNothing%mkCurrencyFail "US" :: Maybe CurrencyNothing&mkCurrencyFail "usd" :: Maybe CurrencyNothing&mkCurrencyFail "USD" :: Maybe CurrencyJust USD haspara"Parser that parses currency codes.,MP.runParser currencyCodeParser "Example" ""Left (ParseErrorBundle {bundleErrors = TrivialError 0 (Just EndOfInput) (fromList []) :| [], bundlePosState = PosState {pstateInput = "", pstateOffset = 0, pstateSourcePos = SourcePos {sourceName = "Example", sourceLine = Pos 1, sourceColumn = Pos 1}, pstateTabWidth = Pos 8, pstateLinePrefix = ""}})-MP.runParser currencyCodeParser "Example" " "Left (ParseErrorBundle {bundleErrors = TrivialError 0 (Just (Tokens (' ' :| ""))) (fromList []) :| [], bundlePosState = PosState {pstateInput = " ", pstateOffset = 0, pstateSourcePos = SourcePos {sourceName = "Example", sourceLine = Pos 1, sourceColumn = Pos 1}, pstateTabWidth = Pos 8, pstateLinePrefix = ""}})-MP.runParser currencyCodeParser "Example" "a"Left (ParseErrorBundle {bundleErrors = TrivialError 0 (Just (Tokens ('a' :| ""))) (fromList []) :| [], bundlePosState = PosState {pstateInput = "a", pstateOffset = 0, pstateSourcePos = SourcePos {sourceName = "Example", sourceLine = Pos 1, sourceColumn = Pos 1}, pstateTabWidth = Pos 8, pstateLinePrefix = ""}})-MP.runParser currencyCodeParser "Example" "A"Left (ParseErrorBundle {bundleErrors = TrivialError 1 (Just EndOfInput) (fromList []) :| [], bundlePosState = PosState {pstateInput = "A", pstateOffset = 0, pstateSourcePos = SourcePos {sourceName = "Example", sourceLine = Pos 1, sourceColumn = Pos 1}, pstateTabWidth = Pos 8, pstateLinePrefix = ""}}).MP.runParser currencyCodeParser "Example" "AB"Left (ParseErrorBundle {bundleErrors = TrivialError 2 (Just EndOfInput) (fromList []) :| [], bundlePosState = PosState {pstateInput = "AB", pstateOffset = 0, pstateSourcePos = SourcePos {sourceName = "Example", sourceLine = Pos 1, sourceColumn = Pos 1}, pstateTabWidth = Pos 8, pstateLinePrefix = ""}})/MP.runParser currencyCodeParser "Example" "ABC" Right "ABC"0MP.runParser currencyCodeParser "Example" "ABCD" Right "ABCD"2MP.runParser currencyCodeParser "Example" " ABCD "Left (ParseErrorBundle {bundleErrors = TrivialError 0 (Just (Tokens (' ' :| ""))) (fromList []) :| [], bundlePosState = PosState {pstateInput = " ABCD ", pstateOffset = 0, pstateSourcePos = SourcePos {sourceName = "Example", sourceLine = Pos 1, sourceColumn = Pos 1}, pstateTabWidth = Pos 8, pstateLinePrefix = ""}}) haspara Converts a  to a 2-tuple of  values.*toCurrencyTuple (CurrencyPair "EUR" "USD") (EUR,USD) hasparaConverts a 2-tuple of  values to a . fromCurrencyTuple ("EUR", "USD")EUR/USD haspara instance for . Aeson.encode ("USD" :: Currency) "\"USD\"" haspara instance for .3Aeson.eitherDecode "\"\"" :: Either String CurrencyLeft "Error in $: Currency code error! Expecting at least 3 uppercase ASCII letters, but received: "4Aeson.eitherDecode "\"A\"" :: Either String CurrencyLeft "Error in $: Currency code error! Expecting at least 3 uppercase ASCII letters, but received: A"5Aeson.eitherDecode "\"AB\"" :: Either String CurrencyLeft "Error in $: Currency code error! Expecting at least 3 uppercase ASCII letters, but received: AB"6Aeson.eitherDecode "\"ABC\"" :: Either String Currency Right ABC7Aeson.eitherDecode "\"ABCD\"" :: Either String Currency Right ABCDhaspara instance for ."USD" :: CurrencyUSDhaspara instance for ."USD" :: CurrencyUSDhaspara instance for .CurrencyPair "EUR" "USD"EUR/USD    None& %(-.0235678;>?hasparaType definition for string modifiers that uppercase a given symbol.None) %(-./0235678;<=>?!haspara!Type encoding for account values."This definition provides both the ! and an arbitrary object identifying the account. This arbitrary nature provides flexibility to use-site to use its own account identity and accompanying information when required.,let acc = Account AccountKindAsset (1 ::Int)Data.Aeson.encode acc#"{\"kind\":\"ASSET\",\"object\":1}"8Data.Aeson.decode @(Account Int) (Data.Aeson.encode acc)Just (Account {accountKind = AccountKindAsset, accountObject = 1})5Data.Aeson.decode (Data.Aeson.encode acc) == Just accTrue!haspara&Type encoding for ledger account type.This type covers both balance sheet and income statement account types: For balance sheet accounts:Asset (") Liability (#)Equity ($)For income statement accounts: Revenue (%) Expense (&)   and    instances, too: *Data.Aeson.decode @AccountKind "\"ASSET\""Just AccountKindAsset.Data.Aeson.decode @AccountKind "\"LIABILITY\""Just AccountKindLiability+Data.Aeson.decode @AccountKind "\"EQUITY\""Just AccountKindEquity,Data.Aeson.decode @AccountKind "\"REVENUE\""Just AccountKindRevenue,Data.Aeson.decode @AccountKind "\"EXPENSE\""Just AccountKindExpense"Data.Aeson.encode AccountKindAsset "\"ASSET\""&Data.Aeson.encode AccountKindLiability"\"LIABILITY\""#Data.Aeson.encode AccountKindEquity "\"EQUITY\""$Data.Aeson.encode AccountKindRevenue "\"REVENUE\""$Data.Aeson.encode AccountKindExpense "\"EXPENSE\""'haspara+Provides textual representation of a given !. accountKindText AccountKindAsset"Asset"$accountKindText AccountKindLiability "Liability"!accountKindText AccountKindEquity"Equity""accountKindText AccountKindRevenue "Revenue""accountKindText AccountKindExpense "Expense"  !&%$#"' !&%$#"' None' %(-./0235678;>?>7hasparaType definition for unsigned 8 values.8hasparaType encoding for quantity values with a given scaling (digits after the decimal point).42 :: Quantity 04242 :: Quantity 142.042 :: Quantity 242.0041 + 1 :: Quantity 242.0043 - 1 :: Quantity 242.002 * 3 * 7 :: Quantity 242.00negate (-42) :: Quantity 242.00abs (-42) :: Quantity 242.00signum (-42) :: Quantity 2-1.00fromInteger 42 :: Quantity 242.00mkQuantity 0.415 :: Quantity 20.42mkQuantity 0.425 :: Quantity 20.425mkQuantityLossless 0.42 :: Either String (Quantity 2) Right 0.426mkQuantityLossless 0.415 :: Either String (Quantity 2)7Left "Underflow while trying to create quantity: 0.415";haspara Constructs 8 values from  values in a lossy way.This function uses @> in case that the lossless attempt fails. We could have used @ directly. However, @ is doing too much (see A). Therefore, we are first attempting a lossless construction (see <) and we fallback to @) in case the lossless construction fails.mkQuantity 0 :: Quantity 00mkQuantity 0 :: Quantity 10.0mkQuantity 0 :: Quantity 20.00mkQuantity 0.04 :: Quantity 10.0mkQuantity 0.05 :: Quantity 10.0mkQuantity 0.06 :: Quantity 10.1mkQuantity 0.14 :: Quantity 10.1mkQuantity 0.15 :: Quantity 10.2mkQuantity 0.16 :: Quantity 10.2mkQuantity 0.04 :: Quantity 20.04mkQuantity 0.05 :: Quantity 20.05mkQuantity 0.06 :: Quantity 20.06mkQuantity 0.14 :: Quantity 20.14mkQuantity 0.15 :: Quantity 20.15mkQuantity 0.16 :: Quantity 20.16mkQuantity 0.04 :: Quantity 30.040mkQuantity 0.05 :: Quantity 30.050mkQuantity 0.06 :: Quantity 30.060mkQuantity 0.14 :: Quantity 30.140mkQuantity 0.15 :: Quantity 30.150mkQuantity 0.16 :: Quantity 30.160<haspara Constructs 8 values from  values in a lossy way.2mkQuantityLossless 0 :: Either String (Quantity 0)Right 02mkQuantityLossless 0 :: Either String (Quantity 1) Right 0.02mkQuantityLossless 0 :: Either String (Quantity 2) Right 0.005mkQuantityLossless 0.04 :: Either String (Quantity 1)8Left "Underflow while trying to create quantity: 4.0e-2"5mkQuantityLossless 0.05 :: Either String (Quantity 1)8Left "Underflow while trying to create quantity: 5.0e-2"5mkQuantityLossless 0.06 :: Either String (Quantity 1)8Left "Underflow while trying to create quantity: 6.0e-2"5mkQuantityLossless 0.14 :: Either String (Quantity 1)6Left "Underflow while trying to create quantity: 0.14"5mkQuantityLossless 0.15 :: Either String (Quantity 1)6Left "Underflow while trying to create quantity: 0.15"5mkQuantityLossless 0.16 :: Either String (Quantity 1)6Left "Underflow while trying to create quantity: 0.16"5mkQuantityLossless 0.04 :: Either String (Quantity 2) Right 0.045mkQuantityLossless 0.05 :: Either String (Quantity 2) Right 0.055mkQuantityLossless 0.06 :: Either String (Quantity 2) Right 0.065mkQuantityLossless 0.14 :: Either String (Quantity 2) Right 0.145mkQuantityLossless 0.15 :: Either String (Quantity 2) Right 0.155mkQuantityLossless 0.16 :: Either String (Quantity 2) Right 0.165mkQuantityLossless 0.04 :: Either String (Quantity 3) Right 0.0405mkQuantityLossless 0.05 :: Either String (Quantity 3) Right 0.0505mkQuantityLossless 0.06 :: Either String (Quantity 3) Right 0.0605mkQuantityLossless 0.14 :: Either String (Quantity 3) Right 0.1405mkQuantityLossless 0.15 :: Either String (Quantity 3) Right 0.1505mkQuantityLossless 0.16 :: Either String (Quantity 3) Right 0.160=hasparaRounds given quantity by k digits.hasparaMultiplies two quantities with different scales and rounds back to the scale of the frst operand.times (mkQuantity 0.42 :: Quantity 2) (mkQuantity 0.42 :: Quantity 2)0.18?haspara0Multiplies two quantities with different scales.timesLossless (mkQuantity 0.42 :: Quantity 2) (mkQuantity 0.42 :: Quantity 2)0.1764@haspara$Auxiliary function for constructing 8 values.See ; why we need this function and why we haven't used it as the direct implementation of ;.Call-sites should avoid using this function directly due to its performance characteristics.AhasparaRounds a given scientific into a new scientific with given max digits after decimal point.$This uses half-even rounding method.roundScientific 0 0.40.0roundScientific 0 0.50.0roundScientific 0 0.61.0roundScientific 0 1.41.0roundScientific 0 1.52.0roundScientific 0 1.62.0roundScientific 1 0.040.0roundScientific 1 0.050.0roundScientific 1 0.060.1roundScientific 1 0.140.1roundScientific 1 0.150.2roundScientific 1 0.160.2roundScientific 1 3.6503.6roundScientific 1 3.7403.7roundScientific 1 3.7493.7roundScientific 1 3.7503.8roundScientific 1 3.7513.8roundScientific 1 3.7603.8roundScientific 1 (-3.650)-3.6roundScientific 1 (-3.740)-3.7roundScientific 1 (-3.749)-3.7roundScientific 1 (-3.750)-3.8roundScientific 1 (-3.751)-3.8roundScientific 1 (-3.760)-3.8;TODO: Refactor to improve the performance of this function.Bhaspara instance for 8.show (42 :: Quantity 2)"42.00"42 :: Quantity 242.00ChasparaFractional arithmetic over 8 values. import Numeric.Decimal?arithM (fromRational 0.42) :: Either SomeException (Quantity 2) Right 0.42arithM (fromRational 0.415) :: Either SomeException (Quantity 2)1Left PrecisionLoss (83 % 200) to 2 decimal spacesarithM $ (fromRational 0.84) / (fromRational 2) :: Either SomeException (Quantity 2) Right 0.42arithM $ (fromRational 0.42) / (fromRational 0) :: Either SomeException (Quantity 2)Left divide by zerolet a = 84 :: Quantity 2let b = 2 :: Quantity 2let c = 0 :: Quantity 2?arithM (Arith a / Arith b) :: Either SomeException (Quantity 2) Right 42.00arithM (Arith a / Arith b / Arith c) :: Either SomeException (Quantity 2)Left divide by zeroDhasparaNumeric arithmetic over 8 values. import Numeric.Decimallet a = Arith (mkQuantity 10) + Arith (mkQuantity 32) :: Arith (Quantity 2) arithMaybe a Just 42.004arithM (41 + 1) :: Either SomeException (Quantity 2) Right 42.004arithM (43 - 1) :: Either SomeException (Quantity 2) Right 42.007arithM (2 * 3 * 7) :: Either SomeException (Quantity 2) Right 42.007arithM (signum 42) :: Either SomeException (Quantity 2) Right 1.00:arithM (signum (-42)) :: Either SomeException (Quantity 2) Right -1.004arithM (abs 42) :: Either SomeException (Quantity 2) Right 42.007arithM (abs (-42)) :: Either SomeException (Quantity 2) Right 42.00?@A 89:7;<=>?@ANone) %(-./0235678;<=>?JG Mhaspara3Type encoding for FX rate quotation database for a .ShasparaType encoding for a dictionary-based FX rate quotation database for various  values.Thaspara:Type encoding for FX rate quotations with fixed precision.%An FX rate quotation is a 3-tuple of: +a currency pair the rate is quoted for, and-a date that the quotation is effective as of,0a (positive) rate as the value of the quotation.VhasparaCurrency pair of the FX rate.WhasparaActual date of the FX rate.Xhaspara%(Positive) rate value of the FX rate.YhasparaSmart constructor for T values within   context.The rate is expected to be a positive value. If it is not, the function will throw an error.mkFxQuoteError @(Either _) @2 (read "2021-12-31") "EUR" "USD" 1.16Right (MkFxQuote {fxQuotePair = EUR/USD, fxQuoteDate = 2021-12-31, fxQuoteRate = Refined 1.16})mkFxQuoteError @(Either _) @2 (read "2021-12-31") "EUR" "USD" (-1.16)Left "Can not create FX Rate. Error was: The predicate (GreaterThan 0) failed with the message: Value is not greater than 0\n"ZhasparaSmart constructor for T values within  context.The rate is expected to be a positive value. If it is not, the function will fail. >>> mkFxQuoteFail Maybe 2 (read "2021-12-31") EUR USD 1.16 Just (MkFxQuote {fxQuotePair = EUR/USD, fxQuoteDate = 2021-12-31, fxQuoteRate = Refined 1.16}) >>> mkFxQuoteFail Maybe 2 (read "2021-12-31") EUR USD (-1.16) Nothing[hasparaUnsafe T constructor that s if it fails.7mkFxQuoteUnsafe @2 (read "2021-12-31") "EUR" "USD" 1.16MkFxQuote {fxQuotePair = EUR/USD, fxQuoteDate = 2021-12-31, fxQuoteRate = Refined 1.16}:mkFxQuoteUnsafe @2 (read "2021-12-31") "EUR" "USD" (-1.16)......Can not create FX Rate. Error was: The predicate (GreaterThan 0) failed with the message: Value is not greater than 0...\haspara9Attempts to find and return the FX quotation for a given  as of a give  in a given S.]haspara:Attempts to find and return the FX quotation as of a give  in a given M.YhasparaDate of the FX quotation.haspara)Base currency (from) of the FX quotation.haspara(Quote currency (to) of the FX quotation.haspara+FX quotation rate, expected to be positive.ZhasparaDate of the FX quotation.haspara)Base currency (from) of the FX quotation.haspara(Quote currency (to) of the FX quotation.haspara+FX quotation rate, expected to be positive.[hasparaDate of the FX quotation.haspara)Base currency (from) of the FX quotation.haspara(Quote currency (to) of the FX quotation.haspara+FX quotation rate, expected to be positive.\haspara/FX quotation database to perform the lookup on.haspara3Currency pair we are looking for the quotation for.haspara.Date the quotation we look for is valid as of.MNRQPOSTUXWVYZ[\]TUXWVYZ[SMNRQPO\]None) %(-./0235678;<=>?R dhaspara*Type encoding of exceptions thrown by the   module.ehasparaIndicates that we received a currency other than the expected currency.fhasparaIndicates that we received a currency other than the expected currency.ghasparaIndicates that we received a currency other than the expected currency.hhaspara$Type encoding of a monetary context.ihasparaConverts the given monetary value in one currency to another currency.Note that the conversion is performed with an FX rate quotation as of the date of the given monetary value.jhasparaConverts the given monetary value in one currency to another currency as of the given date. The rule is:  convertAsofM  DATE2  CCY2 (Money  DATE1  CCY1  QTY1) === convertM  CCY2 (Money  DATE2  CCY1  QTY1) khaspara(Type encoding for dated monetary values.'A dated monetary value is a 3-tuple of: 2a date when the monetary value is effective as of,'the currency of the monetary value, and#the quantity of the monetary value.phasparaAttempts to convert the given k to another using the given T value.This function runs some guards before attempting to do the conversion: Base currency of the FX rate quotation should be the same as the currency of the monetary value, throws e otherwise.Date of the FX rate quotation should be equal to or greater than the date of the monetary value, throws f otherwise.(Rate of the FX rate quotation should be 16 if the base and quote quotation are same, throws g otherwise.ehasparaExpected currencyhasparaReceived currencyfhasparaDate on and onwards of interesthaspara Date receivedghaspara6FX rate quotation that is interpreted as inconsistent. dgfehjiklonmp klonmhjipdgfeNone' %(-./0235678;>?Vyhaspara7Type encoding of an economic increment/decrement event.The event explicitly carries the date and quantity information along with a parameterized, arbitrary object providing the source of the event. :set -XDataKindslet date = read "2021-01-01"let oid = 1 :: Int7let qty = $$(Refined.refineTH 42) :: UnsignedQuantity 2'let event = EventDecrement date oid qty"let json = Data.Aeson.encode eventjson"{\"qty\":42.0,\"type\":\"DECREMENT\",\"obj\":1,\"date\":\"2021-01-01\"}"%Data.Aeson.decode @(Event Int 2) json2Just (EventDecrement 2021-01-01 1 (Refined 42.00))$Data.Aeson.decode json == Just eventTrue|hasparaReturns the date of the event.}haspara'Returns the source object of the event.~hasparaNegates the event.hasparaSmart constuctor for y values.hasparaDate of the event.hasparaSource object of the event.hasparaQuantity of the event.y{z|}~y{z|}~None) %(-./0235678;<=>?_^hasparaEncoding of a posting entry. :set -XDataKindsimport Refinedlet date = read "2021-01-01"let oid = 1 :: Int/let qty = $$(refineTH 42) :: UnsignedQuantity 2#let entry = EntryDebit date oid qtylet json = Aeson.encode entryjson"{\"qty\":42.0,\"type\":\"DEBIT\",\"obj\":1,\"date\":\"2021-01-01\"}"(Aeson.decode json :: Maybe (Entry Int 2).Just (EntryDebit 2021-01-01 1 (Refined 42.00))Aeson.decode json == Just entryTruehasparaType encoding for a posting.:set -XDataKindsimport Haspara.Accountingimport Refined$import qualified Data.Aeson as Aeson)import qualified Data.List.NonEmpty as NElet date = read "2021-01-01"let oid = 1 :: Int/let qty = $$(refineTH 42) :: UnsignedQuantity 2'let event = EventDecrement date oid qtylet account = Account AccountKindAsset ("Cash" :: String, 1 ::Int)9let posting = Posting . NE.fromList $ [(event, account)]let json = Aeson.encode postingjson"[[{\"qty\":42.0,\"type\":\"DECREMENT\",\"obj\":1,\"date\":\"2021-01-01\"},{\"kind\":\"ASSET\",\"object\":[\"Cash\",1]}]]"8Aeson.decode json :: Maybe (Posting (String, Int) Int 2)Just (Posting ((EventDecrement 2021-01-01 1 (Refined 42.00),Account {accountKind = AccountKindAsset, accountObject = ("Cash",1)}) :| []))!Aeson.decode json == Just postingTruehasparaType encoding of a ledger item.hasparaType encoding of a ledger.haspara&Creates a ledger from a given list of  values.hasparaAdds a new entry to a ledger.haspara*Returns the list of posting event sources.hasparaPosts an event.haspara&Returns the date of the posting entry.haspara*Returns the quantity of the posting entry.haspara/Returns the source object of the posting entry.haspara0Returns the debit quantity of the posting entry.haspara1Returns the credit quantity of the posting entry.hasparaConsumes an event and a type of account, and produces a posting entry."Note the following map as a guide:Kind of accountDebitCreditAssetIncreaseDecrease LiabilityDecreaseIncreaseEquity/CapitalDecreaseIncreaseIncome/RevenueDecreaseIncreaseExpenseCostDividendIncreaseDecreaseNone& %(-.0235678;>?`+ !"#$%&'yz{|}~+ !"#$%&'yz{|}~ None& %(-.0235678;>?`5 789:;<=>?@AMNRQOPSTUXVWYZ[\]dgefhijklomnp None& %(-.0235678;>?dhaspara Constructs a 8 value at compile-time using -XTemplateHaskell.!$$(quantityTH 0.00) :: Quantity 20.00!$$(quantityTH 0.09) :: Quantity 20.09"$$(quantityTH 0.009) :: Quantity 2...6..."Underflow while trying to create quantity: 9.0e-3"..."$$(quantityTH 0.009) :: Quantity 30.009haspara Constructs a  value at compile-time using -XTemplateHaskell.$$(currencyTH "USD")USD$$(currencyTH "usd")......Currency code error! Expecting at least 3 uppercase ASCII letters, but received: usd...haspara Constructs a  value at compile-time using -XTemplateHaskell.$$(currencyPairTH "EUR" "USD")EUR/USD$$(currencyPairTH "USD" "USD")USD/USD$$(currencyPairTH "USD" "eur")......Currency code error! Expecting at least 3 uppercase ASCII letters, but received: eur...None' %(-.0235678;>?e? !"#$%&'()*+,--./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxxyz{|}~     &haspara-0.0.0.2-AxwfIaY3JAe5J0iuX9jCclHaspara.CurrencyHaspara.Internal.AesonHaspara.Accounting.AccountHaspara.QuantityHaspara.FxQuoteHaspara.MonetaryHaspara.Accounting.EventHaspara.Accounting.Ledger Haspara.TH Data.AesonFromJSONToJSONHasparaMonetaryHaspara.Accounting Paths_haspara CurrencyPaircurrencyPairBasecurrencyPairQuoteCurrency MkCurrency currencyCodemkCurrencyErrormkCurrencyFailcurrencyCodeParsertoCurrencyTuplefromCurrencyTuple$fToJSONCurrency$fFromJSONCurrency$fShowCurrency$fIsStringCurrency$fShowCurrencyPair$fEqCurrencyPair$fGenericCurrencyPair$fOrdCurrencyPair$fLiftLiftedRepCurrencyPair$fFromJSONCurrencyPair$fToJSONCurrencyPair $fEqCurrency$fHashableCurrency $fOrdCurrency$fLiftLiftedRepCurrency UpperCase$fStringModifierTYPEUpperCaseAccount accountKind accountObject AccountKindAccountKindAssetAccountKindLiabilityAccountKindEquityAccountKindRevenueAccountKindExpenseaccountKindText$fHashableAccountKind$fHashableAccount $fEqAccount$fGenericAccount $fOrdAccount $fShowAccount$fFromJSONAccount$fToJSONAccount$fEnumAccountKind$fEqAccountKind$fGenericAccountKind$fOrdAccountKind$fShowAccountKind$fFromJSONAccountKind$fToJSONAccountKindUnsignedQuantityQuantity MkQuantity unQuantity mkQuantitymkQuantityLossless roundQuantitytimes timesLossless mkQuantityAuxroundScientific$fShowQuantity$fFractionalArith $fNumArith$fToJSONQuantity$fFromJSONQuantity $fEqQuantity $fOrdQuantity$fGenericQuantity $fNumQuantity$fLiftLiftedRepQuantity$fLiftLiftedRepDecimalFxQuotePairDatabasefxQuotePairDatabasePairfxQuotePairDatabaseTablefxQuotePairDatabaseSincefxQuotePairDatabaseUntilFxQuoteDatabaseFxQuote MkFxQuote fxQuotePair fxQuoteDate fxQuoteRatemkFxQuoteError mkFxQuoteFailmkFxQuoteUnsafe findFxQuotefindFxQuoteAux $fEqFxQuote$fGenericFxQuote $fOrdFxQuote $fShowFxQuote$fFromJSONFxQuote$fToJSONFxQuoteMonetaryExceptionIncompatibleCurrenciesExceptionIncompatibleDatesExceptionInconsistentFxQuoteExceptionconvertM convertAsofMMoney moneyDate moneyCurrency moneyQuantityconvert$fExceptionMonetaryException $fEqMoney$fGenericMoney $fOrdMoney $fShowMoney$fFromJSONMoney $fToJSONMoney$fShowMonetaryExceptionEventEventDecrementEventIncrement eventDate eventObject negateEventmkEvent $fToJSONEvent$fFromJSONEvent $fEqEvent $fOrdEvent $fShowEventEntry EntryDebit EntryCreditPosting LedgerItemledgerItemEntryledgerItemBalanceLedger ledgerAccount ledgerOpening ledgerClosing ledgerRunningmkLedgeraddEntry postingEventspost entryDate entryQuantity entryObject entryDebit entryCredit buildEntry $fToJSONEntry$fFromJSONEntry $fEqLedger$fGenericLedger $fOrdLedger $fShowLedger$fFromJSONLedger$fToJSONLedger$fEqLedgerItem$fGenericLedgerItem$fOrdLedgerItem$fShowLedgerItem$fFromJSONLedgerItem$fToJSONLedgerItem $fEqEntry $fOrdEntry $fShowEntry $fEqPosting$fGenericPosting $fOrdPosting $fShowPosting$fFromJSONPosting$fToJSONPosting quantityTH currencyTHcurrencyPairTH$aeson-1.5.6.0-GY8CLOpb1WuINByNCH12i1Data.Aeson.Types.FromJSONData.Aeson.Types.ToJSON mtl-2.2.2Control.Monad.Error.Class MonadError#text-1.2.5.0-IEal7YJCEpPE23BnjRa8JhData.Text.InternalTextbaseControl.Monad.Fail MonadFail Data.StringIsStringGHC.ShowShow)scientific-0.3.7.0-54K099o0ZwrKaBk8Lh2ascData.Scientific Scientifictemplate-haskellLanguage.Haskell.TH.SyntaxLiftGHC.Errerror time-1.9.3Data.Time.Calendar.DaysDayversion getBinDir getLibDir getDynLibDir getDataDir getLibexecDir getSysconfDirgetDataFileName