From 95d50b25c990e8c945ce2507b16ff3c8b039d286 Mon Sep 17 00:00:00 2001 From: Rutger Broekhoff Date: Mon, 25 Aug 2025 19:48:19 +0200 Subject: OCaml --- app/Data/Iban.hs | 48 ------------------ app/Data/Ledger.hs | 115 -------------------------------------------- app/Data/Ledger/AutoFile.hs | 1 - app/Data/Res.hs | 31 ------------ 4 files changed, 195 deletions(-) delete mode 100644 app/Data/Iban.hs delete mode 100644 app/Data/Ledger.hs delete mode 100644 app/Data/Ledger/AutoFile.hs delete mode 100644 app/Data/Res.hs (limited to 'app/Data') diff --git a/app/Data/Iban.hs b/app/Data/Iban.hs deleted file mode 100644 index d9566b9..0000000 --- a/app/Data/Iban.hs +++ /dev/null @@ -1,48 +0,0 @@ -module Data.Iban (Iban, mkIban, toText) where - -import Control.Applicative ((<|>)) -import Data.Attoparsec.Text as AP -import Data.Char - ( digitToInt, - isAscii, - isDigit, - ord, - toUpper, - ) -import Data.Text qualified as T - -newtype Iban = Iban T.Text deriving (Show, Eq) - -mkIban :: T.Text -> Either String Iban -mkIban t = validateIban t >> return (Iban t) - -validateIban :: T.Text -> Either String () -validateIban = AP.parseOnly $ do - countryCode <- AP.count 2 AP.letter - checkDigits <- AP.count 2 AP.digit - chars <- AP.many1 (AP.letter <|> AP.digit) - endOfInput - if length chars < 30 - then - if valid countryCode checkDigits chars - then return () - else fail $ "IBAN checksum does not match (" ++ countryCode ++ checkDigits ++ chars ++ ")" - else fail "IBAN has more than 34 characters" - where - letterToInt c = ord (toUpper c) - ord 'A' + 10 - charsToInteger = - foldl' - ( \acc -> \case - d - | isDigit d -> acc * 10 + toInteger (digitToInt d) - | isAscii d -> acc * 100 + toInteger (letterToInt d) - | otherwise -> error "unreachable" - ) - 0 - ibanToInteger countryCode checkDigits chars = - charsToInteger chars * 1000000 + charsToInteger countryCode * 100 + charsToInteger checkDigits - valid countryCode checkDigits chars = - ibanToInteger countryCode checkDigits chars `mod` 97 == 1 - -toText :: Iban -> T.Text -toText (Iban t) = t diff --git a/app/Data/Ledger.hs b/app/Data/Ledger.hs deleted file mode 100644 index 4aa5137..0000000 --- a/app/Data/Ledger.hs +++ /dev/null @@ -1,115 +0,0 @@ -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE TypeFamilies #-} - -module Data.Ledger where - -import Data.Constraint.Extras.TH (deriveArgDict) -import Data.Dependent.Map (DMap, fromList, singleton, union, unionWithKey) -import Data.Dependent.Sum ((==>)) -import Data.Functor.Identity -import Data.Functor.Identity (Identity (..)) -import Data.GADT.Compare.TH (deriveGCompare, deriveGEq) -import Data.GADT.Show.TH (deriveGShow) -import Data.Iban -import Data.Map qualified as M -import Data.Text qualified as T -import Data.Time.Calendar -import Data.Time.Clock -import Data.UUID -import GHC.Generics - -data AccountType = Asset | Equity | Liability | Expense | Income - -data TxAction = Inc | Dec - -txaOpp :: TxAction -> TxAction -txaOpp Inc = Dec -txaOpp Dec = Inc - -onDebit :: AccountType -> TxAction -onDebit Asset = Inc -onDebit Equity = Dec -onDebit Liability = Dec -onDebit Expense = Inc -onDebit Income = Dec - -onCredit :: AccountType -> TxAction -onCredit = txaOpp . onDebit - -data TxType - = InterestCtx - | OnlineBankingTx - | RecurrentDirectTx - | PaymentTerminalTx - | CashPaymentTx - | AtmTx - | AutoSaveRoundingTx - | BatchTx - | DirectDebitTx - | PeriodicTx - -data IbanTag = AccountTag | CounterpartyIbanTag deriving (Eq, Enum, Ord, Show) - -data UnitTag = FiledTag | GooglePayTag | AutoRoundSavingsTag deriving (Eq, Enum, Ord, Show) - -data TextTag = DescTag | UserTag | CounterpartyNameTag | ReferenceTag | MandateIdTag | CreditorIdTag | OtherPartyTag | TransactionTag | TerminalTag | CardSeqNoTag | SavingsAccountTag deriving (Eq, Enum, Ord, Show) - -data Label a where - TextLabel :: TextTag -> Label T.Text - IbanLabel :: IbanTag -> Label Iban - UnitLabel :: UnitTag -> Label () - TimestampLabel :: Label UTCTime - -deriveGEq ''Label -deriveGCompare ''Label -deriveGShow ''Label -deriveArgDict ''Label - -type Labels = DMap Label Identity - -data Money = Money Integer deriving (Show) - -infixl 6 +€, -€ - -(+€) :: Money -> Money -> Money -Money x +€ Money y = Money (x + y) - -(-€) :: Money -> Money -> Money -Money x -€ Money y = Money (x - y) - -data Scalar = Amount Money | Rate Integer deriving (Show) - -data AccountId = AccountId [T.Text] deriving (Show) - -data CommodityId = CommodityId UUID deriving (Show) - -data Account = Account - { id :: AccountId, - description :: [T.Text], - commodityId :: CommodityId, - balance :: Money - } - --- A balance assertion is only valid when all transactions before it have been --- cleared and the balance of the account agrees with the amount in the --- assertion. -data BalAssert = BalAssert - { account :: AccountId, - amount :: Money, - labels :: Labels - } - -data Tx = Tx - { cleared :: Maybe Day, - commodityId :: CommodityId, -- the commodity w.r.t. which rates are calculated - debit :: M.Map AccountId Scalar, - credit :: M.Map AccountId Scalar, - labels :: Labels - } - deriving (Show, Generic) - --- data SeqTx = SeqTx [Integer] Tx - -data Entry = TxEntry Tx | BalAssertEntry BalAssert - -data Ledger = Ledger [Entry] diff --git a/app/Data/Ledger/AutoFile.hs b/app/Data/Ledger/AutoFile.hs deleted file mode 100644 index 15a1b16..0000000 --- a/app/Data/Ledger/AutoFile.hs +++ /dev/null @@ -1 +0,0 @@ -module Data.Ledger.AutoFile where diff --git a/app/Data/Res.hs b/app/Data/Res.hs deleted file mode 100644 index 3806e5a..0000000 --- a/app/Data/Res.hs +++ /dev/null @@ -1,31 +0,0 @@ -module Data.Res where - -import Control.Applicative -import Data.String (IsString (fromString)) - -data Res e r = Ok r | Err e - -instance Functor (Res e) where - fmap f (Ok v) = Ok (f v) - fmap _ (Err e) = Err e - -instance Applicative (Res e) where - pure = Ok - (Ok f) <*> (Ok v) = Ok (f v) - (Err e) <*> _ = Err e - _ <*> (Err e) = Err e - -instance Monad (Res e) where - (Ok v) >>= f = f v - (Err e) >>= _ = Err e - -instance (IsString e) => MonadFail (Res e) where - fail = Err . fromString - -instance (IsString e) => Alternative (Res e) where - empty = fail "mzero" - m1@(Ok _) <|> _ = m1 - (Err _) <|> m2 = m2 - -liftEither :: Either e r -> Res e r -liftEither = either Err Ok -- cgit v1.2.3