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

前端 未结 3 1260
南方客
南方客 2020-12-18 17:47

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

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

Is there a way

3条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-12-18 18:38

    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
    

提交回复
热议问题