// F#
type BodyType =
| Sedan
| SUV
type Vehicle =
| Bus of riders:int * capacity:int * basePrice:decimal
| Taxi of riders:int * capacity:int * basePrice:decimal * body:BodyType * fares:int
| Train of riders:int * capacity:int * basePrice:decimal
let vehicle = Bus(riders = 10, capacity = 30, basePrice = 5.00m)
let calculateToll vehicle =
match vehicle with
| Bus(r,c,p) when (double r / double c) < 0.50 -> p + 2.00m
| Bus(r,c,p) when (double r / double c) > 0.90 -> p - 1.00m
| Bus(basePrice = p) -> p
| Taxi(basePrice = p; body = b) when b = SUV -> p + 1.00m
| Taxi(basePrice = p; body = b) when b = Sedan -> p
| Train(basePrice = p; capacity = c) when c = 20 -> p * 1.2m
| Train(basePrice = p) -> p
| _ -> 0m
// C#
Vehicle vehicle = new Bus(Riders: 10, Capacity: 20, BasePrice: 5.00m);
decimal CalculateToll(Vehicle vehicle) => vehicle switch {
Bus b when ((double)b.Riders / b.Capacity) < 0.50 => b.BasePrice + 2.00m,
Bus b when ((double)b.Riders / b.Capacity) > 0.90 => b.BasePrice - 1.00m,
Bus b => b.BasePrice,
Taxi { Body: BodyType.SUV } t => t.BasePrice + 1.00m,
Taxi { Body: BodyType.Sedan } t => t.BasePrice,
Train { Capacity: 20 } t => t.BasePrice * 1.2m,
Train t => t.BasePrice,
{ } => 0m,
_ => throw new ArgumentException(message: "Not a known vehicle type", paramName: nameof(vehicle))
};
public record Vehicle(int Riders, int Capacity, decimal BasePrice);
public record Bus(int Riders, int Capacity, decimal BasePrice) : Vehicle(Riders, Capacity, BasePrice);
public record Train(int Riders, int Capacity, decimal BasePrice) : Vehicle(Riders, Capacity, BasePrice);
public record Taxi(int Riders, int Capacity, decimal BasePrice, BodyType Body, int Fares) : Vehicle(Riders, Capacity, BasePrice);
public enum BodyType {
Sedan,
SUV
}