3 people like it.
Like the snippet!
Finalizing Tesco purchase
The sample shows two different reprezentations of Tesco checkout. The first one stores scanned items - as a list of either purchase or cancel items - and the second stores final bill with product and total quantity. The snippet implements transformation that corresponds to finalizing the purchase.
1:
2:
3:
4:
5:
6:
|
type Code = string
type Name = string
type Price = decimal
type Picture = string
type Product = Product of Code * Name * Picture * Price
type Quantity = decimal
|
1:
2:
3:
4:
5:
6:
|
type LineItem =
| SaleLineItem of int * Product * Quantity
| CancelLineItem of int
/// Purchase is a list of items as they were scanned
type LinePurchase = list<LineItem>
|
1:
2:
|
/// Immutable map stores products and the purchased quantity
type FinalPurchase = Map<Product, Quantity>
|
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
|
/// This function takes a list of scanned lines and
/// produces a final bill. It first removes all cancelled
/// items and then groups products to get total quantity.
let calculateFinal (line:LinePurchase) : FinalPurchase =
line
|> Seq.choose (fun item ->
match item with
| SaleLineItem(id, prod, q) ->
// Check if the item has been cancelled
let cancelled =
line |> Seq.exists (fun item ->
match item with
| CancelLineItem cancelId when cancelId = id -> true
| _ -> false)
if cancelled then None
else Some (prod, q)
| _ -> None )
// Group products and calculate total quantity
|> Seq.groupBy (fun (prod, q) -> prod)
|> Seq.map (fun (prod, items) ->
prod, Seq.sumBy snd items)
|> Map.ofSeq
|
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = System.String
Full name: Microsoft.FSharp.Core.string
type Name = string
Full name: Script.Name
type Price = decimal
Full name: Script.Price
Multiple items
val decimal : value:'T -> decimal (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.decimal
--------------------
type decimal = System.Decimal
Full name: Microsoft.FSharp.Core.decimal
--------------------
type decimal<'Measure> = decimal
Full name: Microsoft.FSharp.Core.decimal<_>
type Picture = string
Full name: Script.Picture
Multiple items
union case Product.Product: Code * Name * Picture * Price -> Product
--------------------
type Product = | Product of Code * Name * Picture * Price
Full name: Script.Product
type Code = string
Full name: Script.Code
type Quantity = decimal
Full name: Script.Quantity
type LineItem =
| SaleLineItem of int * Product * Quantity
| CancelLineItem of int
Full name: Script.LineItem
union case LineItem.SaleLineItem: int * Product * Quantity -> LineItem
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
union case LineItem.CancelLineItem: int -> LineItem
type LinePurchase = LineItem list
Full name: Script.LinePurchase
Purchase is a list of items as they were scanned
type 'T list = List<'T>
Full name: Microsoft.FSharp.Collections.list<_>
type FinalPurchase = Map<Product,Quantity>
Full name: Script.FinalPurchase
Immutable map stores products and the purchased quantity
Multiple items
module Map
from Microsoft.FSharp.Collections
--------------------
type Map<'Key,'Value (requires comparison)> =
interface IEnumerable
interface IComparable
interface IEnumerable<KeyValuePair<'Key,'Value>>
interface ICollection<KeyValuePair<'Key,'Value>>
interface IDictionary<'Key,'Value>
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
member Add : key:'Key * value:'Value -> Map<'Key,'Value>
member ContainsKey : key:'Key -> bool
override Equals : obj -> bool
member Remove : key:'Key -> Map<'Key,'Value>
...
Full name: Microsoft.FSharp.Collections.Map<_,_>
--------------------
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
val calculateFinal : line:LinePurchase -> FinalPurchase
Full name: Script.calculateFinal
This function takes a list of scanned lines and
produces a final bill. It first removes all cancelled
items and then groups products to get total quantity.
val line : LinePurchase
module Seq
from Microsoft.FSharp.Collections
val choose : chooser:('T -> 'U option) -> source:seq<'T> -> seq<'U>
Full name: Microsoft.FSharp.Collections.Seq.choose
val item : LineItem
val id : int
val prod : Product
val q : Quantity
val cancelled : bool
val exists : predicate:('T -> bool) -> source:seq<'T> -> bool
Full name: Microsoft.FSharp.Collections.Seq.exists
val cancelId : int
union case Option.None: Option<'T>
union case Option.Some: Value: 'T -> Option<'T>
val groupBy : projection:('T -> 'Key) -> source:seq<'T> -> seq<'Key * seq<'T>> (requires equality)
Full name: Microsoft.FSharp.Collections.Seq.groupBy
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>
Full name: Microsoft.FSharp.Collections.Seq.map
val items : seq<Product * Quantity>
val sumBy : projection:('T -> 'U) -> source:seq<'T> -> 'U (requires member ( + ) and member get_Zero)
Full name: Microsoft.FSharp.Collections.Seq.sumBy
val snd : tuple:('T1 * 'T2) -> 'T2
Full name: Microsoft.FSharp.Core.Operators.snd
val ofSeq : elements:seq<'Key * 'T> -> Map<'Key,'T> (requires comparison)
Full name: Microsoft.FSharp.Collections.Map.ofSeq
More information