Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constrained types from a type provider (XmlProvider)

Tags:

f#

f#-data

I derive great value from XmlProvider as it gives me a ton of type definitions when I load an XML or XSD. However, consider this XML:

<period>
    <start>01/01/2018</start>
    <end>02/02/2018</end>
</period>

Can I sweet talk the type provider into giving me a constrained data type such that "end" may not precede "start". Or maybe bolt on some constraints after XmlProvider does the heavy lifting?

like image 378
StevePoling Avatar asked Feb 16 '26 04:02

StevePoling


1 Answers

In this case I would treat this as an edge-case, and consider it an "unvalidated model". As such, typically in F#, we would use a validation function to turn that unvalidated model into a validated model. (I usually use Result<'T, 'E> for that.)

let validateXmlDates xml =
    if xml.period.start > xml.period.end then
        Error "Period start must be before period end"
    else Ok xml

Now, anything you do should expect a Result<XmlType, string>, which will allow you to pass it around with a guarantee that it matches your requirements. You may also use Result.bind to chain validations1:

Ok xml
|> Result.bind (validateXmlDates)
|> Result.bind (validateXml...)
|> Result.bind (validateXml...)

Somewhat related reading: Railway Oriented Programming (F# for Fun and Profit)

Once you have the results, a trivial match can be used to trigger the next step:

match validatedXml with
| Ok xml -> ...
| Error str -> ...

You would then do the next logical step in the Ok branch, and handle errors in the Error branch.

1: Result.bind (fn) is effectively a short-hand for the following:

match result with
| Error e -> Error e
| Ok v -> fn v
like image 110
Der Kommissar Avatar answered Feb 20 '26 08:02

Der Kommissar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!