I would like to be able to express some Measure
of a specific type in a variety of ways. This is a very wacky example.
- If we are cooking Lamb, then we will need 3 tablespoons of olive oil, 1 cup of sugar, and 3 ounces of butter.
- If we are cooking pie, then we will need 10 tablespoons of olive oil, and 1 ounce of salt
- If we area cooking steak, then we will need 5 ounces of salt, 4 pounds of ice cream.
I have different measures:
[<Measure>] type Tablespoon
[<Measure>] type Ounce
[<Measure>] type Pounds
We also have the different foods we'd like to cook:
type Foods =
| Lamb
| Pie
| Steak
How do we create a record / function / something to represent the recipe above?
I'm attempting to model something like this:
What is the measure of the accompanying offerings? The accompanying offering for a male or female sheep is an isaron12 of fine flour mixed with a quarter of a hin13 of oil and a quarter of a hin of wine as a wine libation. These are also [the accompanying offerings] for a goat whether small14or large15 and whether male or female and for a ewe, even if she is large. The accompanying offerings of a ram, however, are two esronim mixed with a third of a hin of oil and a third of a hin of wine as a libation. The accompanying offerings of a cow or a calf, whether male or female, are three esronim mixed with a half of a hin of oil and a half of a hin of wine as a libation.
Each accompanying offering is different depending on the animal being offered (sheep/goat/ram).
For your needs, I might not use F#'s units of measure system, and instead model your units as a discriminated union. The reason is because F#'s units of measure are treated as completely different types, so you can't write a list like [ 3.0<Tablespoon>; 0.5<Cup> ]
[ 3.0<Tablespoon>; 0.5<Cup> ]
as F# will throw a type error. But you could do something like the following:
type RecipeUnit =
| Tablespoon
| Cup
| Ounce
| Pound
type Ingredient =
| Butter
| OliveOil
| Sugar
| Salt
type RecipePart = { Amount: float
Unit: RecipeUnit
Item: Ingredient }
let pie = [
{ Amount = 10.0; Unit = Tablespoon; Item = OliveOil }
{ Amount = 1.0; Unit = Ounce; Item = Salt }
]
Or, to give an example with your actual data model:
type Unit =
| Isaron
| Hin
type Ingredient =
| Flour
| Oil
| Wine
type OfferingPart = { Amount: float
Unit: Unit
Item: Ingredient }
type Offering = OfferingPart list
let sheepOffering = [
{ Amount = 1.0; Unit = Isaron; Item = Flour }
{ Amount = 1.0 / 4.0; Unit = Hin; Item = Oil }
{ Amount = 1.0 / 4.0; Unit = Hin; Item = Wine }
]
let goatOffering = sheepOffering
let ramOffering = [
{ Amount = 2.0; Unit = Isaron; Item = Flour }
{ Amount = 1.0 / 3.0; Unit = Hin; Item = Oil }
{ Amount = 1.0 / 3.0; Unit = Hin; Item = Wine }
]
// Etc.
Note that 1.0 / 3.0
is imprecise; if that's a problem, you'll want to model rational fractions (as either a tuple or a 2-item record; I'll assume you don't need help with this one).
PS I assume that "esronim" is the plural of "isaron", and that the two esronim mentioned in the ram's offering are of flour. If I got that wrong, adjust my example accordingly.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.