Skip to content

Commit 14ff31e

Browse files
committed
add 'Adding Meaning To Primitive Types' blog post samples
1 parent e8753c1 commit 14ff31e

File tree

2 files changed

+176
-0
lines changed

2 files changed

+176
-0
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
open System
2+
type IncomeSource =
3+
| Salary
4+
| Royalty
5+
6+
type ExpenseCategory =
7+
| Food
8+
| Entertainment
9+
10+
type Money = Money of decimal with
11+
static member (+) (Money m1, Money m2) = Money (m1 + m2)
12+
static member get_Zero() = Money 0m
13+
static member DivideByInt ((Money m), (x : int)) =
14+
Decimal.Divide(m, Convert.ToDecimal(x))
15+
|> Money
16+
17+
18+
type Income = {
19+
Amount : Money
20+
Source : IncomeSource
21+
}
22+
23+
type Expense = {
24+
Amount : Money
25+
Category : ExpenseCategory
26+
}
27+
28+
type Transaction =
29+
| Credit of Income
30+
| Debit of Expense
31+
32+
33+
34+
// Transaction list -> Money
35+
let balance transactions =
36+
transactions
37+
|> List.map (
38+
function
39+
| Credit x ->
40+
let (Money m) = x.Amount
41+
m
42+
| Debit y ->
43+
let (Money m) = y.Amount
44+
-m
45+
)
46+
|> List.sum
47+
|> Money
48+
49+
50+
let rec private getExpenses' expenseCategory transactions expenses =
51+
match transactions with
52+
| [] -> expenses
53+
| x :: xs ->
54+
match x with
55+
| Debit expense when expense.Category = expenseCategory ->
56+
(expense :: expenses)
57+
|> getExpenses' expenseCategory xs
58+
| _ -> getExpenses' expenseCategory xs expenses
59+
60+
let getExpenses expenseCategory transactions =
61+
getExpenses' expenseCategory transactions []
62+
63+
let getExpenditure expenseCategory transactions =
64+
getExpenses expenseCategory transactions
65+
|> List.sumBy (fun expense -> expense.Amount)
66+
67+
// ExpenseCategory -> Transaction list list -> Money
68+
let averageExpenditure expenseCategory transactionsList =
69+
transactionsList
70+
|> List.map (getExpenditure expenseCategory)
71+
|> List.average
72+
73+
let transactions =
74+
75+
[ {Category = Food; Amount = Money 10m}
76+
{Category = Food; Amount = Money 15m}
77+
] |> List.map Debit
78+
79+
80+
let transactions2 =
81+
82+
[ {Category = Food; Amount = Money 5m}
83+
{Category = Food; Amount = Money 10m}
84+
] |> List.map Debit
85+
86+
87+
averageExpenditure Food [transactions;transactions2]
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
type IncomeSource =
2+
| Salary
3+
| Royalty
4+
5+
type ExpenseCategory =
6+
| Food
7+
| Entertainment
8+
9+
type Money = Money of decimal
10+
11+
type Income = {
12+
Amount : Money
13+
Source : IncomeSource
14+
}
15+
16+
type Expense = {
17+
Amount : Money
18+
Category : ExpenseCategory
19+
}
20+
21+
type Transaction =
22+
| Credit of Income
23+
| Debit of Expense
24+
25+
26+
27+
// Transaction list -> Money
28+
let balance transactions =
29+
transactions
30+
|> List.map (
31+
function
32+
| Credit x ->
33+
let (Money m) = x.Amount
34+
m
35+
| Debit y ->
36+
let (Money m) = y.Amount
37+
-m
38+
)
39+
|> List.sum
40+
|> Money
41+
42+
43+
let rec private getExpenses' expenseCategory transactions expenses =
44+
match transactions with
45+
| [] -> expenses
46+
| x :: xs ->
47+
match x with
48+
| Debit expense when expense.Category = expenseCategory ->
49+
(expense :: expenses)
50+
|> getExpenses' expenseCategory xs
51+
| _ -> getExpenses' expenseCategory xs expenses
52+
53+
let getExpenses expenseCategory transactions =
54+
getExpenses' expenseCategory transactions []
55+
56+
let getExpenditure expenseCategory transactions =
57+
getExpenses expenseCategory transactions
58+
|> List.map (fun expense ->
59+
let (Money m) = expense.Amount
60+
m
61+
)
62+
|> List.sum
63+
|> Money
64+
65+
66+
// ExpenseCategory -> Transaction list list -> Money
67+
let averageExpenditure expenseCategory transactionsList =
68+
transactionsList
69+
|> List.map (getExpenditure expenseCategory)
70+
|> List.map (fun (Money m) -> m)
71+
|> List.average
72+
|> Money
73+
74+
75+
let transactions =
76+
77+
[ {Category = Food; Amount = Money 10m}
78+
{Category = Food; Amount = Money 15m}
79+
] |> List.map Debit
80+
81+
82+
let transactions2 =
83+
84+
[ {Category = Food; Amount = Money 5m}
85+
{Category = Food; Amount = Money 10m}
86+
] |> List.map Debit
87+
88+
89+
averageExpenditure Food [transactions;transactions2]

0 commit comments

Comments
 (0)