Last active
March 7, 2024 10:46
-
-
Save ianrussellsoftwarepark/63e01137659bca179ad9f670901143b0 to your computer and use it in GitHub Desktop.
Result composition from F# Essentials Lectures Session 5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Customer = { | |
Id : int | |
IsVip : bool | |
Credit : decimal | |
} | |
type GetPurchasesError = | |
| HasOddId of int | |
type IncreaseCreditIfVipError = | |
| IsNotVip | |
type UpgradeCustomerError = | |
| GetPurchases of GetPurchasesError | |
| IncreaseCredit of IncreaseCreditIfVipError | |
// Customer -> Result<(Customer * decimal),GetPurchasesError> | |
let getPurchases (customer:Customer) : Result<(Customer * decimal),GetPurchasesError> = | |
if customer.Id % 2 = 0 then Ok (customer, 120M) | |
else Error (HasOddId customer.Id) | |
// Customer * decimal -> Customer | |
let tryPromoteToVip purchases = | |
let customer, amount = purchases | |
if amount > 100M then { customer with IsVip = true } | |
else customer | |
// Customer -> Result<Customer,IncreaseCreditIfVipError> | |
let increaseCreditIfVip (customer:Customer) : Result<Customer,IncreaseCreditIfVipError> = | |
if customer.IsVip then Ok { customer with Credit = customer.Credit + 100m } | |
else Error IsNotVip | |
// let upgradeCustomer (customer:Customer) : Result<Customer,UpgradeCustomerError> = | |
// customer | |
// |> getPurchases | |
// |> Result.mapError (fun err -> GetPurchases err) | |
// |> Result.map tryPromoteToVip | |
// |> fun result -> | |
// match result with | |
// | Ok cust -> | |
// match increaseCreditIfVip cust with | |
// | Ok res -> Ok res | |
// | Error err -> Error (IncreaseCredit err) | |
// | Error err -> Error err | |
// let upgradeCustomer customer : Result<Customer,UpgradeCustomerError> = | |
// customer | |
// |> getPurchases | |
// |> Result.mapError GetPurchases | |
// |> Result.map tryPromoteToVip | |
// |> Result.bind (fun cust -> | |
// match increaseCreditIfVip cust with | |
// | Ok res -> Ok res | |
// | Error ex -> ex |> IncreaseCredit |> Error | |
let mapError f result = | |
match result with | |
| Ok res -> Ok res | |
| Error ex -> ex |> f |> Error | |
// let upgradeCustomer customer : Result<Customer,UpgradeCustomerError> = | |
// customer | |
// |> getPurchases | |
// |> Result.mapError GetPurchases | |
// |> Result.map tryPromoteToVip | |
// |> Result.bind (fun cust -> | |
// increaseCreditIfVip cust | |
// |> Result.mapError (fun ex -> IncreaseCredit ex)) | |
// let upgradeCustomer customer : Result<Customer,UpgradeCustomerError> = | |
// customer | |
// |> getPurchases | |
// |> Result.mapError GetPurchases | |
// |> Result.map tryPromoteToVip | |
// |> Result.bind (fun cust -> | |
// cust | |
// |> increaseCreditIfVip | |
// |> Result.mapError IncreaseCredit) | |
// let upgradeCustomer customer : Result<Customer,UpgradeCustomerError> = | |
// customer | |
// |> getPurchases | |
// |> Result.mapError GetPurchases | |
// |> Result.map tryPromoteToVip | |
// |> Result.bind (fun cust -> increaseCreditIfVip cust |> Result.mapError IncreaseCredit) | |
let upgradeCustomer customer : Result<Customer,UpgradeCustomerError> = | |
customer | |
|> getPurchases | |
|> Result.mapError GetPurchases | |
|> Result.map tryPromoteToVip | |
|> Result.bind (increaseCreditIfVip >> Result.mapError IncreaseCredit) | |
// Result.map : ('a -> 'b) -> Result<'a, 'c> -> Result<'b, 'c> | |
// Result.bind : ('a -> Result<'b, 'c>) -> Result<'a, 'c> -> Result<'b, 'c> | |
// Result.mapError : ('a -> 'b) -> Result<'c, 'a> -> Result<'c, 'b> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment