bitterharvest’s diary

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

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

1.小さな会社を運用してみる

小さな会社での登場人物が独立したエージェントとして活躍すると、並行処理での会計システムの稼働状況を観察できる。そこで、乱数を発生させ、営業の担当者は0.1-0.5秒の間のランダムな時間に50個の商品を販売し、購買の担当者は0.5-1秒の間のランダムな時間に100個の製品を購入したとする。このようにすると、購買と販売の担当者が同じ時間に取引したり、在庫数が0になったりする現象が観察できるはずである。
また、会計の担当者は5秒毎の時間に財務諸表を出力し、投資家は、最初に一度だけ、10000万円投資することとした。この会社は、商品が売れている限りは、1個当たり20円の収入があるので、最初の投資額が十分であれば、会社は儲かり続けるようになっている。
それでは、用意した関数を見ていくことにする。
乱数の発生と、そこから得られた時間の遅延をもたらす関数は次のようになる。randomDelayBは購買担当者の取引間隔を与え、randomDelayBは営業担当者の取引間隔を与える。

randomDelayB = do r <- randomRIO (500000,1000000)
                  threadDelay r

randomDelayS = do r <- randomRIO (100000,500000)
                  threadDelay r

購買担当者の行動を表す関数buyer’は以下の通りである。

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."
      randomDelayB
      buyer' n product purchasing cash   

営業担当者の行動を表す関数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." 
      randomDelayS
      salesperson' n product cash sales
||<	
会計担当者の行動を表す関数accountant’は以下の通りである。
>|haskell|
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" 
      threadDelay 5000000
      accountant' cash sales purchasing stock product

2.シミュレーション

各エージェントの用意ができたので、シミュレーションを行うこととする。そのプログラムは以下のようになる。なお、プログラムの中で、ForkIOはそれに続く関数を子プロセスとして起動する。これにより、営業、購買、会計の担当者が並行して動作するようになる。

simulation = do cash <- newCash 0
                sales <- newSales 0
                purchasing <- newPurchasing 0
                stock <- newStock 0
                product <- newProduct 0
                founder 10000 cash stock
                forkIO $ buyer' 50 product purchasing cash   
                forkIO $ salesperson' 100 product cash sales
                forkIO $ accountant' cash sales purchasing stock product

3.問題

購入数、販売数を変えることでどのような変化が観察されるか?

4.問題

上記のプログラムでは、仕訳伝票を用いていない。仕訳伝票を利用することで、完成度の高いプログラムとしなさい。

5.損益

営業活動の中で損が発生すると、この会社の財務諸表は現実味を帯びてくる。在庫数が増えすぎたとき、その一部を捨て去るようにしたらどうなるか?

6.発展問題

入出力をウェブベースで行えるようにすると、上記のプログラムは実用的な会計システム