Created
October 4, 2021 14:03
-
-
Save carlosble/b4273e705a5683029c4c1d3fe6326fd5 to your computer and use it in GitHub Desktop.
Ejemplo F# de uniones discriminadas y productos
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 Percentage = Percentage of float | |
type ResidentDiscount = ResidentDiscount of Percentage | |
type FamilyDiscount = FamilyDiscount of Percentage | |
type SpecialResidentDiscount = SpecialResidentDiscount of Percentage | |
type BussinesClub = BussinesClub of Percentage | |
type SpanishSubsidy = | |
| SpecialResident of SpecialResidentDiscount | |
| Resident of ResidentDiscount | |
| Family of FamilyDiscount | |
type FlightDiscount = | |
| Subsidy of SpanishSubsidy | |
| Bussines of BussinesClub | |
| SubsidyPlusBussines of ResidentDiscount * BussinesClub | |
| NoDiscount | |
type FlightOrderRequest = { | |
SpanishSubsidy: SpanishSubsidy option | |
BussinesClub: BussinesClub option | |
// passenger info over here... | |
} | |
type CalculateDiscountPercentage = FlightDiscount -> Percentage | |
type DiscountFromOrder = FlightOrderRequest -> FlightDiscount | |
module Percentage = | |
let add p1 p2 = | |
let (Percentage a) = p1 | |
let (Percentage b) = p2 | |
let sum = a + b | |
Percentage sum | |
let zero = | |
Percentage(0.0) | |
let value (Percentage percentage) = percentage | |
let max p1 p2 = | |
let (Percentage a) = p1 | |
let (Percentage b) = p2 | |
if (a > b) then | |
p1 | |
else | |
p2 | |
module ResidentDiscount = | |
let create : ResidentDiscount = | |
ResidentDiscount (Percentage 75.0) | |
let percentage (ResidentDiscount p) = p | |
module FamilyDiscount = | |
let create : FamilyDiscount = | |
FamilyDiscount (Percentage 10.0) | |
let percentage (FamilyDiscount p) = p | |
module SpecialResidentDiscount = | |
let create : SpecialResidentDiscount = | |
SpecialResidentDiscount (Percentage 75.0) | |
let percentage (SpecialResidentDiscount p) = p | |
module SpanishSubsidy = | |
let percentage (subsidy: SpanishSubsidy) = | |
match subsidy with | |
| SpecialResident (d) -> SpecialResidentDiscount.percentage d | |
| Resident (d) -> ResidentDiscount.percentage d | |
| Family (d) -> FamilyDiscount.percentage d | |
module BussinesClub = | |
let create : BussinesClub = | |
BussinesClub (Percentage 20.0) | |
let cumulativePercentage (bussines: BussinesClub) (resident: ResidentDiscount) = | |
let (BussinesClub p1) = bussines | |
let (ResidentDiscount p2) = resident | |
Percentage.add (Percentage.max p1 p2) (Percentage 10.0) | |
let percentage (BussinesClub p) = p | |
let discountFromOrder : DiscountFromOrder = | |
fun request -> | |
match request.BussinesClub with | |
| Some(bussinesClub) -> | |
match request.SpanishSubsidy with | |
| Some(subsidy) -> | |
match subsidy with | |
| Resident (rd) -> SubsidyPlusBussines (rd, request.BussinesClub.Value) | |
| _ -> Subsidy (subsidy) | |
| None -> Bussines (request.BussinesClub.Value) | |
| None -> | |
match request.SpanishSubsidy with | |
| Some(subsidy) -> Subsidy (subsidy) | |
| None -> NoDiscount | |
let calculatePercentage : CalculateDiscountPercentage = | |
fun discount -> | |
match discount with | |
| Subsidy (s) -> SpanishSubsidy.percentage s | |
| Bussines (b) -> BussinesClub.percentage b | |
| SubsidyPlusBussines (s, b) -> BussinesClub.cumulativePercentage b s | |
| NoDiscount -> Percentage.zero | |
// ---------------------------------------------------------------- | |
// USAGE EXAMPLES: | |
// ---------------------------------------------------------------- | |
let flightOrder : FlightOrderRequest = { | |
SpanishSubsidy = Family FamilyDiscount.create |> Some; | |
BussinesClub = None | |
} | |
let flightOrder2 : FlightOrderRequest = { | |
SpanishSubsidy = Resident ResidentDiscount.create |> Some; | |
BussinesClub = Some BussinesClub.create; | |
} | |
let discount = discountFromOrder flightOrder | |
printfn "Discount1: %A" discount | |
let discount2 = discountFromOrder flightOrder2 | |
printfn "Discount2: %A" discount2 | |
printfn "Calculated percentage: %A" (calculatePercentage discount) | |
printfn "Calculated percentage: %A" (calculatePercentage discount2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment