bitterharvest’s diary

A Bitter Harvestは小説の題名。作者は豪州のPeter Yeldham。苦闘の末に勝ちえた偏見からの解放は命との引換になったという悲しい物語

Haskellを利用して簡単な会計システムを実現する(4)

1.取引をHaskellで記述する

勘定科目が用意できたので、簡単な取引が行えるようにする。この会計システムを利用する人は、小さな会社にも関わらず、購買の担当者、営業の担当者、会計の担当者、投資家の4人とする。
購買の担当者buyerは、商品を購入するが、その時の単価は80円であるとする。購買の担当者が\(n\)個の商品を購入したとき、商品の在庫が\(n\)個増加し、仕入高が\(80n\)円増加し、現金が\(80n\)円減少するので、関数buyerは以下のようになる。
なお、このプログラムでatomicallyという関数が出てくる。通常、トランザクション処理には、原子性(Atomicitiy)、一貫性(Consistensy)、独立性(Isolation)、耐久性(Durability)の4つが求められる。原子性は、トランザクションに含まれるそれぞれの処理が、すべて実行されるか、全く実行されない性質である。atomicallyはこれと同じ意味である。以下のプログラムでは、atomically以下にあるbuy, addP, subCの三つの関数は、product, purchasing, cashの三つのトランザクションメモリを用いているが、 他のプロセスあるいはスレッドに邪魔されることなく、これらのメモリからの読み込みと書き込みは一貫性を保持して確実に行われる。

buyer n product purchasing cash =
   do atomically $ do 
                       buy product n
                       addP purchasing (n * 80)
                       subC cash (n * 80)
      putStrLn $ "A buyer buys " ++ show n ++ " products by " ++ show (n * 80) ++ " yen."

営業の担当者salespersonは、商品を販売するが、その時の単価は100円であるとする。営業の担当者が\(n\)個の商品を購入したとき、商品の在庫が\(n\)個減少し、現金が\(100n\)円増加し、売上高が\(100n\)円増加するので、関数salespersonは以下のようになる。

salesperson n product cash sales =
   do atomically $ do
                       sell product n
                       addC cash (n * 100)      
                       addS sales (n * 100) 
      putStrLn $ "A salesperson sells " ++ show n ++ " products by " ++ show (n * 100) ++ " yen." 

投資家fouderが、投資すると、現金と資本金の両方が増大するので、関数founderは以下の通りとなる。

founder x cash stock =
   do atomically $ do
                       addC cash x
                       addT stock x
      putStrLn $ "A founder invests " ++ show x ++ " yen." 

会計の担当者accountantは、その時点での貸借対照表、損益計算書、棚卸資産を提示する。関数accountantは以下の通りとなる。

accountant cash sales purchasing stock product =
   do amountC <- readTVarIO cash
      amountS <- readTVarIO sales
      amountP <- readTVarIO purchasing
      amountT <- readTVarIO stock
      amountR <- readTVarIO product
      putStrLn $ "Balance Sheet"
      putStrLn $ "Cash:  " ++ show amountC ++ " Profit:  " ++ show (amountC - amountT)
      putStrLn $ "             Capital: " ++ show amountT  
      putStrLn $ "Profit & Loss"
      putStrLn $ "Sales: " ++ show amountS ++ " Cost:    " ++ show amountP  
      putStrLn $ "             Profit:  " ++ show (amountS - amountP)  
      putStrLn $ "Inventory"
      putStrLn $ "Goods: " ++ show amountR++ " product"  

2.取引を行う

上記の関数を用いて、投資家が10000円投資をし、購買の担当者が100個の商品を仕入れ、営業の担当者が80個の商品を売りさばいたときの経理上の数字を見ることにする。以下のようにして、test1を実行する。

test1 = do 
         cash <- newCash 0
         sales <- newSales 0
         purchasing <- newPurchasing 0
         stock <- newStock 0
         product <- newProduct 0
         founder 10000 cash stock
         buyer 100 product purchasing cash
         salesperson 80 product cash sales
         accountant cash sales purchasing stock product
         buyer 80 product purchasing cash
         salesperson 95 product cash sales
         accountant cash sales purchasing stock product

次のような出力を得るはずである。
f:id:bitterharvest:20140725073703p:plain