A VERY simple application scenario of the Maybe Monad in F#
open FSharpx.Option | |
/// Type synonims | |
type ProductId = string | |
type Price = float | |
type Inventory() = | |
let inv_ = new System.Collections.Generic.Dictionary<ProductId, Price>() | |
member this.Stock (id : ProductId) (price : Price) = | |
inv_.Add(id, price) | |
member this.Price (id : ProductId) = | |
try | |
Some(inv_.[id]) | |
with | |
| :? System.Collections.Generic.KeyNotFoundException -> None | |
let inline (|@|) (p1 : Price option) (p2 : Price option) = | |
maybe{ | |
let! v1 = p1 | |
let! v2 = p2 | |
return! Some(v1 + v2) | |
} | |
let reporter (priceSum : Price option) : unit = | |
match priceSum with | |
| Some(p) -> printfn "Total price: %g." p | |
| None -> printfn "One or more id not found." | |
//Initialize a basic inventory and throw inside a bunch of items | |
let inventory = new Inventory() | |
inventory.Stock "MyWidget" 10.3 | |
inventory.Stock "Gizmos" 4.34 | |
inventory.Stock "Foo1000" 8.12 | |
//Sum prices | |
inventory.Price("MyWidget") |@| inventory.Price("Gizmos") |> reporter | |
//A further step, price sum pipelining | |
inventory.Price("MyWidget") | |
|> (|@|) (inventory.Price("Gizmos")) | |
|> (|@|) (inventory.Price("Foo1000")) | |
|> reporter | |
//A failing computation | |
inventory.Price("MyWidget") | |
|> (|@|) (inventory.Price("Gizmos")) | |
|> (|@|) (inventory.Price("DoesNotExist")) | |
|> reporter | |
//A completely automatic procedure | |
let sumAndReport (inventory : Inventory) (ids : ProductId list) : unit = | |
let basket = List.map (fun pid -> inventory.Price(pid)) ids | |
in List.reduce (fun p1 p2 -> p1 |@| p2) basket | |
|> reporter |
This comment has been minimized.
This comment has been minimized.
Thanks! I'm preparing a blog post about it. In order:
Bye! |
This comment has been minimized.
This comment has been minimized.
Piping operators is unnecessary in this case, compare |
This comment has been minimized.
This comment has been minimized.
Ok, in this case yes, I though you were generalizing to never use the pipe operator and I was puzzled :D Bye! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
Very nice! I forked this with a few suggestions: https://gist.github.com/2276291