Skip to content

Instantly share code, notes, and snippets.

View Gryff's full-sized avatar

Liam Griffin-Jowett Gryff

View GitHub Profile

bank-kata

Implement a bank account that can deposit, withdraw and print a statement to the console.

Follow the Tell, don't ask principle. All methods should be void.

void Deposit(int)
void Withdraw(int)
void PrintStatement()

Develop an API that moves a Mars Rover around on a grid.

Rules

  • You are given the initial starting point (0,0,N) of a rover.
  • 0,0 are X,Y co-ordinates on a grid of (10,10).
  • N is the direction it is facing (i.e. N,S,E,W).
  • L and R allow the rover to rotate left and right.
  • M allows the rover to move one point in the current direction.
  • The rover receives a char array of commands e.g. RMMLM and returns the finishing point after the moves e.g. 2,1,N
-- we'll need an instance of `Writer String` for `MonadCurrentDateTime` for our test
instance MonadCurrentDateTime (Writer String) where
currentDateTime = pure firstOfJan2019
testMyBank :: StateT [Transaction] (Writer String) ()
testMyBank = do
deposit 200
withdraw 100
deposit 3000
printStatement
deposit amount = do
now <- lift currentDateTime
modify $ \transactions -> transactions ++ [Deposit amount now]
instance MonadCurrentDateTime IO where
currentDateTime = getCurrentTime -- this comes from Data.Time
-- in our test file
instance MonadCurrentDateTime Identity where
currentDateTime = pure firstOfJan2019
deposit :: (Monad m, MonadCurrentDateTime m) => Int -> StateT [Transaction] m ()
withdraw :: (Monad m, MonadCurrentDateTime m) => Int -> StateT [Transaction] m ()
class MonadCurrentDateTime m where
currentDateTime :: m UTCTime
firstOfJan2019 = UTCTime (fromGregorian 2019 01 01) (secondsToDiffTime 0)
-- ...
deposit amount = modify $ \transactions -> transactions ++ [Deposit amount firstOfJan2019]
-- same for `withdraw`, and in test functions
import Data.Time
data Transaction = Deposit Int UTCTime | Withdrawal Int UTCTime
-- our Transaction type
data Transaction = Deposit Int | Withdrawal Int
-- our bank functions
deposit :: Monad m => Int -> StateT [Transaction] m ()
deposit amount = modify $ \transactions -> transactions ++ [Deposit amount]
withdraw :: Monad m => Int -> StateT [Transaction] m ()
withdraw amount = modify $ \transactions -> transactions ++ [Withdrawal amount]