Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
579 views
in Technique[技术] by (71.8m points)

f# - Is it possible to enforce that a Record respects some invariants?

Suppose I wanted to create a Record type that represents acceptable min/max bounds:

type Bounds = { Min: float; Max: float }

Is there a way to enforce that Min < Max? It is easy to write a validateBounds function, I was just wondering if there was a better way to do this.

Edit: I realized that for this specific example I could probably get away with exposing two properties and re-order the arguments, so let's say we were trying to do

type Person = { Name: string }

and Name needs to have at least one character.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Here's another solution based on protection levels:

module MyModule =
    type Bounds = private { _min: float; _max: float } with
        // define accessors, a bit overhead
        member public this.Min = this._min
        member public this.Max = this._max
        static member public Make(min, max) =
            if min > max then raise (ArgumentException("bad values"))
            {_min=min; _max=max}

    // The following line compiles fine,
    // e.g. within your module you can do "unsafe" initialization
    let myBadBounds = {_min=10.0; _max=5.0}

open MyModule
let b1 = Bounds.Make(10.0, 20.0) // compiles fine
let b1Min = b1.Min
let b2 = Bounds.Make(10.0, 5.0) // throws an exception
// The following line does not compile: the union cases of the type 'Bounds'
// are not accessible from this code location
let b3 = {_min=10.0; _max=20.0}
// The following line takes the "bad" value from the module
let b4 = MyModule.myBadBounds

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...