-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCart.fs
More file actions
91 lines (74 loc) · 2.26 KB
/
Cart.fs
File metadata and controls
91 lines (74 loc) · 2.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// namespace Foo
// or module Cart =
// <code indented>
module Cart
type CartItem = string // placeholder
type EmptyState = NoItems // this is a single union type, duh
// trying to force Client apps to handle empty state explicitly
type ActiveState = {
UnpaidItems : CartItem list
}
type PaidForState = {
PaidItems : CartItem list;
Payment : decimal
}
type Cart =
| Empty of EmptyState
| Active of ActiveState
| PaidFor of PaidForState
// actions
let addToEmptyState item =
Cart.Active {
UnpaidItems = [item]
}
let addToActiveState state item =
let newItemList = item :: state.UnpaidItems
Cart.Active {
state with UnpaidItems = newItemList
}
let removeFromActiveState state item =
let newItemList =
state.UnpaidItems
|> List.filter (fun i -> i <> item)
match newItemList with
| [] -> Cart.Empty NoItems
| _ -> Cart.Active { state with UnpaidItems = newItemList }
let payForActiveState state amount =
Cart.PaidFor {PaidItems = state.UnpaidItems; Payment = amount}
type EmptyState with
member __.Add = addToEmptyState
type ActiveState with
member this.Add = addToActiveState this
member this.Remove = removeFromActiveState this
member this.Pay = payForActiveState this
let addItemToCart cart item =
match cart with
| Empty state -> state.Add item
| Active state -> state.Add item
| PaidFor _ ->
printfn "ERROR: the cart is paid for"
cart
let removeItemFromCart cart item =
match cart with
| Empty _ ->
printfn "ERROR: the cart is empty"
cart
| Active state -> state.Remove item
| PaidFor _ ->
printfn "ERROR: the cart is paid for"
cart
let displayCart cart =
match cart with
| Empty _ ->
printfn "The cart is empty"
| Active state ->
printfn "The cart contains %A unpaid items"
state.UnpaidItems
| PaidFor state ->
printfn "The cart cotains %A paid items. Amount paid: %f"
state.PaidItems state.Payment
type Cart with
static member NewCart = Cart.Empty NoItems
member this.Add = addItemToCart this
member this.Remove = removeItemFromCart this
member this.Display = displayCart this