简体   繁体   中英

how to formulate a recipe in 1 record type or function

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.

  1. If we are cooking Lamb, then we will need 3 tablespoons of olive oil, 1 cup of sugar, and 3 ounces of butter.
  2. If we are cooking pie, then we will need 10 tablespoons of olive oil, and 1 ounce of salt
  3. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM