# Monthly Archives: December 2016

In previous posts, I have discussed my implementation details for the Bank Account kata.

This post will provide details on how I property-based test one of my functions. Specifically, I show the source code for testing a deposit.

Here are the types:

```type Account =
| Checking of decimal
| Savings  of decimal

type Commands =
| Withdraw of Account * decimal
| Deposit  of Account * decimal
| Transfer of Account * Account * decimal

type Response =
| Withdrawal       of State * State
| WithdrawalFailed of Account * decimal

| Deposited        of State * State
| DepositFailed    of Account * decimal

| Transferred      of TransferSummary   * decimal
| TransferFailed   of Account * Account * decimal

and State =
| BeforeDeposit of Account * decimal
| AfterDeposit  of Account

| BeforeWithdrawal of Account * decimal
| AfterWithdrawal  of Account

and TransferSummary = {
FromBalanceBefore: Account ; ToBalanceBefore: Account
FromBalanceAfter:  Account ; ToBalanceAfter:  Account }
```

The function is below:

```let handleDeposit = function
| Deposit (account , amount) when amount > 0m && amount <= 1000000000m ->
Some (Deposited((BeforeDeposit (account , amount),
AfterDeposit  (credit account amount) )))
| Deposit (account , amount) ->
Some (DepositFailed (account , amount))
| _ -> None
```

The following code is a property-based test for the function above:

```(*Tests*)
open FsCheck
open FsCheck.Xunit

type Run100KAttribute() =
inherit PropertyAttribute(
MaxTest = 100000,
QuietOnSuccess = true)

[<Run100K>]
let ``deposits greater than zero AND less than 1 million always succeed`` () =

// Setup
let validDeposits = function
| Deposit (acct , bal) -> bal > 0m &&
bal <= 1000000m
| _ -> false

let isDeposited deposit = function
| Some v -> match v with
| Deposited _ -> true
| _           -> false
| _ -> false

// Test
Arb.generate<Commands>
|> Gen.filter validDeposits
|> Arb.fromGen
|> Prop.forAll
<| fun deposit -> handleDeposit deposit
|> isDeposited```

In the Bank Account Kata (vol. 1 & 2) video, I expressed disappointment on how I implemented my handlers.

The handlers were the following:

```let handleWithdraw =  function
| Withdraw (account , amount) ->
if canWithdraw account amount then
Some (Withdrawal(BeforeWithdrawal (account ,     amount),
AfterWithdrawal  (debit account amount)))
else Some (WithdrawalFailed (account, amount) )
| _ -> None

let handleDeposit =   function
| Deposit   (account , amount) ->
if amount > 0m then
Some (Deposited((BeforeDeposit (account , amount),
AfterDeposit  (credit account amount) )))
else Some (DepositFailed (account , amount))
| _ -> None

let handleTransfer =  function
| Transfer (fromAccount, toAccount, amount) ->
if canWithdraw fromAccount amount then
Some (Transferred ({ FromBalanceBefore=fromAccount
ToBalanceBefore=  toAccount

FromBalanceAfter= debit  fromAccount amount
ToBalanceAfter=   credit toAccount   amount } ,

amount))
else Some (TransferFailed (fromAccount, toAccount, amount))
| _ -> None
```

Let’s look at the first function:

```let handleWithdraw =  function
| Withdraw (account , amount) ->
if canWithdraw account amount then
Some (Withdrawal(BeforeWithdrawal (account ,     amount),
AfterWithdrawal  (debit account amount)))
else Some (WithdrawalFailed (account, amount) )
| _ -> None
```

The function above did not read as well as I would like. As a result I refactored the function to fully embrace pattern matching:

```let handleWithdraw =  function
| Withdraw (account , amount) when canWithdraw account amount ->
Some (Withdrawal(BeforeWithdrawal (account ,     amount),
AfterWithdrawal  (debit account amount)))
| Withdraw (account , amount) when not (canWithdraw account amount) ->
Some (WithdrawalFailed (account, amount) )
| _ -> None
```

Here’s the refactoring of all three functions:

```let handleWithdraw =  function
| Withdraw (account , amount) when canWithdraw account amount ->
Some (Withdrawal(BeforeWithdrawal (account ,     amount),
AfterWithdrawal  (debit account amount)))
| Withdraw (account , amount) when not (canWithdraw account amount) ->
Some (WithdrawalFailed (account, amount) )
| _ -> None

let handleDeposit =   function
| Deposit (account , amount) when amount > 0m ->
Some (Deposited((BeforeDeposit (account , amount),
AfterDeposit  (credit account amount) )))
| Deposit (account , amount) when amount <= 0m ->
Some (DepositFailed (account , amount))
| _ -> None

let handleTransfer =  function
| Transfer (fromAccount, toAccount, amount) when canWithdraw fromAccount amount ->
Some (Transferred ({ FromBalanceBefore=fromAccount
ToBalanceBefore=  toAccount
FromBalanceAfter= debit  fromAccount amount
ToBalanceAfter=   credit toAccount   amount } ,
amount))

| Transfer (fromAccount, toAccount, amount) when not (canWithdraw fromAccount amount) ->
Some (TransferFailed (fromAccount, toAccount, amount))
| _ -> None
```

Angry Developer: I’m having a developer identity crisis trying to figure out what my niche should be.  Seems like there’s always web work, but no two shops are using more than a few of the same tools and frameworks.  I’d really like to avoid becoming an expert at some doomed technology, if that can be helped.

Scott Nimrod: I think Angular is a safe bet for the next 6 months.
😉

Angry Developer: You mean Angular2 –Angular is obsolete shit that must be replaced now.
Scott Nimrod: Yea. That.

Angry Developer: That’s the funnest part of JavaScript dev.  By the time you’re an expert at a stack, it’s changed completely.

Angry Developer: I completely wasted about 5 hours last week learning, trying, and failing with code examples and tutorials on Ionic and Angular because (once I looked more carefully) I was looking a examples for the previous frameworks (which were current a few month ago).

Angry Developer: Doh!

Angry Developer: I much prefer slower, more thoughtful languages and frameworks.  I haven’t had to throw away more than a few pages of what I knew about .NET 1.1

Angry Developer: The JS hackers are changing their frameworks constantly because they didn’t think things through very carefully in the initial design.

In the previous Bank Account kata, I attempted to implement happy path logic using a function-driven approach to later discover my types that would complement them.

Note that my initial implementation did not cover edge case scenarios.

For example:
Can one withdraw an amount that exceeds their balance?

Can one deposit absolutely nothing into their account?

My types were updated to the following:

```type Account =
| Checking of decimal
| Savings  of decimal

type Commands =
| Withdraw of Account * decimal
| Deposit  of Account * decimal
| Transfer of Account * Account * decimal

type Response =
| Withdrawal       of State * State
| WithdrawalFailed of Account * decimal

| Deposited        of State * State
| DepositFailed    of Account * decimal

| Transferred      of TransferSummary   * decimal
| TransferFailed   of Account * Account * decimal

and State =
| BeforeDeposit of Account * decimal
| AfterDeposit  of Account

| BeforeWithdrawal of Account * decimal
| AfterWithdrawal  of Account

and TransferSummary = {
FromBalanceBefore: Account ; ToBalanceBefore: Account
FromBalanceAfter:  Account ; ToBalanceAfter:  Account }
```

My functions were updated to the following:

```(*Functions*)
let balanceOf = function
| Checking v
| Savings  v

let update account amount operator = account |>  function
| Checking v -> Checking (v + (operator * amount))
| Savings  v -> Savings  (v + (operator * amount))

let debit       account amount =  update account amount (- 1m)
let credit      account amount =  update account amount (+ 1m)
let canWithdraw account amount = balanceOf account >= amount

let handleWithdraw =  function
| Withdraw (account , amount) ->
if canWithdraw account amount then
Some (Withdrawal(BeforeWithdrawal (account ,     amount),
AfterWithdrawal  (debit account amount)))
else Some (WithdrawalFailed (account, amount) )
| _ -> None

let handleDeposit =   function
| Deposit   (account , amount) ->
if amount > 0m then
Some (Deposited((BeforeDeposit (account , amount),
AfterDeposit  (credit account amount) )))
else Some (DepositFailed (account , amount))
| _ -> None

let handleTransfer =  function
| Transfer (fromAccount, toAccount, amount) ->
if canWithdraw fromAccount amount then
Some (Transferred ({ FromBalanceBefore=fromAccount
ToBalanceBefore=  toAccount

FromBalanceAfter= debit  fromAccount amount
ToBalanceAfter=   credit toAccount   amount } ,

amount))
else Some (TransferFailed (fromAccount, toAccount, amount))
| _ -> None
```

Here are some client calls for the updated code:

```(*Client*)
let deposit =   handleDeposit  (Deposit  (Checking 100m , 10m))
let withdrawl = handleWithdraw (Withdraw (Savings  10m , 10m))
let transfer =  handleTransfer (Transfer (Checking 100m , Savings 150m , 10m))
```

Here’s the output from the client calls:

```val deposit : Response option =
Some
(Deposited
(BeforeDeposit (Checking 100M,10M),AfterDeposit (Checking 110M)))
val withdrawl : Response option =
Some
(Withdrawal
(BeforeWithdrawal (Savings 10M,10M),AfterWithdrawal (Savings 0M)))
val transfer : Response option =
Some (Transferred ({FromBalanceBefore = Checking 100M;
ToBalanceBefore = Savings 150M;
FromBalanceAfter = Checking 90M;
ToBalanceAfter = Savings 160M;},10M))
```

The entire domain is below:

```module BankAccountImpl2

type Account =
| Checking of decimal
| Savings  of decimal

type Commands =
| Withdraw of Account * decimal
| Deposit  of Account * decimal
| Transfer of Account * Account * decimal

type Response =
| Withdrawal       of State * State
| WithdrawalFailed of Account * decimal

| Deposited        of State * State
| DepositFailed    of Account * decimal

| Transferred      of TransferSummary   * decimal
| TransferFailed   of Account * Account * decimal

and State =
| BeforeDeposit of Account * decimal
| AfterDeposit  of Account

| BeforeWithdrawal of Account * decimal
| AfterWithdrawal  of Account

and TransferSummary = {
FromBalanceBefore: Account ; ToBalanceBefore: Account
FromBalanceAfter:  Account ; ToBalanceAfter:  Account }

(*Functions*)
let balanceOf = function
| Checking v
| Savings  v

let update account amount operator = account |>  function
| Checking v -> Checking (v + (operator * amount))
| Savings  v -> Savings  (v + (operator * amount))

let debit       account amount =  update account amount (- 1m)
let credit      account amount =  update account amount (+ 1m)
let canWithdraw account amount = balanceOf account >= amount

let handleWithdraw =  function
| Withdraw (account , amount) ->
if canWithdraw account amount then
Some (Withdrawal(BeforeWithdrawal (account ,     amount),
AfterWithdrawal  (debit account amount)))
else Some (WithdrawalFailed (account, amount) )
| _ -> None

let handleDeposit =   function
| Deposit   (account , amount) ->
if amount > 0m then
Some (Deposited((BeforeDeposit (account , amount),
AfterDeposit  (credit account amount) )))
else Some (DepositFailed (account , amount))
| _ -> None

let handleTransfer =  function
| Transfer (fromAccount, toAccount, amount) ->
if canWithdraw fromAccount amount then
Some (Transferred ({ FromBalanceBefore=fromAccount
ToBalanceBefore=  toAccount

FromBalanceAfter= debit  fromAccount amount
ToBalanceAfter=   credit toAccount   amount } ,

amount))
else Some (TransferFailed (fromAccount, toAccount, amount))
| _ -> None

(*Client*)
let deposit =   handleDeposit  (Deposit  (Checking 100m , 10m))
let withdrawl = handleWithdraw (Withdraw (Savings  10m , 10m))
let transfer =  handleTransfer (Transfer (Checking 100m , Savings 150m , 10m))
```

I wrote some F# code for handling bank account transactions.

I wrote the program by using a function driven approach instead of a type driven approach.

The main handlers are the following:

```let handleWithdraw = function
| Withdraw   (account , amount) ->
Some  (BeforeWithdrawal (account , -1m * amount),
AfterWithdrawal  (debit account amount) )
| _ -> None

let handleDeposit =   function
| Deposit   (account , amount) ->
Some (BeforeDeposit (account , 1m * amount),
AfterDeposit  (credit account amount) )
| _ -> None

let handleTransfer =  function
| Transfer (fromAccount, toAccount, amount) ->
Some (Transferred ({ FromBalanceBefore=fromAccount
ToBalanceBefore=  toAccount

FromBalanceAfter= debit  fromAccount amount
ToBalanceAfter=   credit toAccount   amount } ,

amount))
| _ -> None
```

The supporting functions that back the handlers are as follows:

```let update account amount operator = account |>  function
| Checking v -> Checking (v + (operator * amount))
| Savings  v -> Savings  (v + (operator * amount))

let debit  account amount =  update account amount (- 1m)
let credit account amount =  update account amount (+ 1m)
```

Here are the types:

```type Account =
| Checking of decimal
| Savings  of decimal

type Commands =
| Withdraw of Account * decimal
| Deposit  of Account * decimal
| Transfer of Account * Account * decimal

type Response =
| Withdrawal  of Account
| Deposited   of Account
| Transferred of TransferSummary * decimal

and Transaction =
| BeforeDeposit of Account * decimal
| AfterDeposit  of Account

| BeforeWithdrawal of Account * decimal
| AfterWithdrawal  of Account

and TransferSummary = {
FromBalanceBefore: Account ; ToBalanceBefore: Account
FromBalanceAfter:  Account ; ToBalanceAfter:  Account }
```

The entire program is below:

```module BankAccountImpl

type Account =
| Checking of decimal
| Savings  of decimal

type Commands =
| Withdrawal of Account * decimal
| Deposit   of Account * decimal
| Transfer  of Account * Account * decimal

type Response =
| Withdrawal  of Account
| Deposited   of Account
| Transferred of TransferSummary * decimal

and Transaction =
| BeforeDeposit of Account * decimal
| AfterDeposit  of Account

| BeforeWithdrawal of Account * decimal
| AfterWithdrawal  of Account

and TransferSummary = {
FromBalanceBefore: Account ; ToBalanceBefore: Account
FromBalanceAfter:  Account ; ToBalanceAfter:  Account }

(*Functions*)
let update account amount operator = account |>  function
| Checking v -> Checking (v + (operator * amount))
| Savings  v -> Savings  (v + (operator * amount))

let debit  account amount =  update account amount (- 1m)
let credit account amount =  update account amount (+ 1m)

let handleWithdraw = function
| Withdraw  (account , amount) ->
Some (BeforeWithdrawal (account , -1m * amount),
AfterWithdrawal  (debit account amount) )
| _ -> None

let handleDeposit =   function
| Deposit   (account , amount) ->
Some (BeforeDeposit (account , 1m * amount),
AfterDeposit  (credit account amount) )
| _ -> None

let handleTransfer =  function
| Transfer (fromAccount, toAccount, amount) ->
Some (Transferred ({ FromBalanceBefore=fromAccount
ToBalanceBefore=  toAccount

FromBalanceAfter= debit  fromAccount amount
ToBalanceAfter=   credit toAccount   amount } ,

amount))
| _ -> None

(*Client*)
let deposit =    handleDeposit   (Deposit  (Checking 100m , 10m))
let withdraw =   handleWithdraw  (Withdrawal (Savings 100m , 10m))
let transfer =   handleTransfer  (Transfer (Checking 100m , Savings 150m , 10m))
```

In this video, I talk to Gabriel about what’s required of him to succeed in today’s software industry:

In this video, I talk to Adam Wright about arrogance and helping others: