vendredi 15 juillet 2016

How to restrict a DU/ADT to certain case identifiers/value constructors

How would I approach the following situatiuon?
I have a DU (for example a Currency) and some record type. Now for the record type fields I have the requierements that the actual values for a given instance should al be of the same case identifier (or in Haskell the same value constructor)

type Currency =
    | USD of decimal
    | EUR of decimal

type PositionalData = {
    grossAmount: Currency;
    pos1: Currency;
    pos2: Currency;
}

for example the following is valid

let valid = {
    grossAmount = USD 10.0m;
    pos1 = USD 7.0m;
    pos2 = USD 3.0m;
}

where as this example should be invalid

let wrong = {
    grossAmount = USD 10.0m;
    pos1 = USD 7.0m;
    pos2 = EUR 3.0m;
    ^^^^^^^^^^^^^^^^
}

I know this particular example can be solved in F# using Units of Measurement. But its easy to envision an example that is not solvable via that mechanism. So I like to ask you to consider a more generic answer and not necessarily one that just solves the give code example.

Looking forward to your brain dumps ;-)

PS: for all the Haskeleers around - It would be interesting to see how ADT (maybe in combination wit higher kinded types) can solve that.

Aucun commentaire:

Enregistrer un commentaire