Statically permitted type parameters in F # are not resolved as expected, or: cannot propagate type parameters?

TL; DR: how to repeat / redistribute static type parameters in F #? For the example function below, I cannot get it to work.

Here's a minimal (I think) version that illustrates what I'm trying to achieve (i.e. a method that checks the range of values ​​based on the statically known presence of properties MinValueand MaxValuefor the type)

type MyByte = MyByte of byte with
    static member MinValue = MyByte Byte.MinValue
    static member MaxValue = MyByte Byte.MaxValue
    static member op_Explicit (MyByte x): int64 = int64 x
    static member op_Explicit (MyByte x): double = double x

let inline isWithinMinMaxRange< ^b, ^a when 
                    ^b: comparison 
                    and ^a: comparison 
                    and ^b: (static member MinValue: ^b) 
                    and ^b: (static member MaxValue: ^b)
                    and ^b : (static member op_Explicit: ^b -> ^a) > 
                    (value: ^a) =

    let minRange = ((^b) : (static member MinValue: ^b) ())
    let maxRange = ((^b) : (static member MaxValue: ^b) ())
    let cast v = (^b : (static member op_Explicit: ^b -> ^a) v)

    value > cast minRange && value < cast maxRange

// works as can be expected
let test() = isWithinMinMaxRange<MyByte, _> 256.0

// does not work, complains it cannot convert to 'a
let inline test2 v = isWithinMinMaxRange<MyByte, _> v

The above code generates a compilation error in test2:

error FS0043: type "MyByte" does not support conversion to type "a"

, : , ? , , , , .

, , ( ):

let test< ^source, ^value
        when ^source: comparison 
        and ^value: comparison 
        // next line is redundant, but shows my experiments ;)
        and (^source or ^value) : (static member op_Explicit: ^value -> ^source)
        and ^source: (static member op_Explicit: ^source -> MyByte)
        and ^value: (static member op_Explicit: ^value -> sbyte) 
        and ^source: (static member MinValue: ^source) 
        and ^source: (static member MaxValue: ^source)> (v: ^value) =
    isWithinMinMaxRange< ^source, ^value> v

:

FS0001: 'when ^ source: ( op_Explicit: ^ source → ^? 9104)'

FS0043: 'when ^ source: ( op_Explicit: ^ source → ^? 9104)

, - , trickbook, " " , .

:

  • , , ? ( , , )
  • , ? ^?9104 ( )?
  • ? , , , . , .
+6

All Articles