General class with restriction of measure

How do I create a generic class in F # with a constraint so that the type is a measure?

I tried this, but a2 and b2 don't throw errors:

open Microsoft.FSharp.Data.UnitSystems.SI.UnitNames

type Vector2D_A<[<Measure>] 'u>(x : float<'u>, y : float<'u>) =
    member this.X = x
    member this.Y = y

type Vector2D_B<'t, [<Measure>] 'u>(x : 't, y : 't) =
    member this.X = x
    member this.Y = y

type Vector2D_C<'t>(x : 't, y : 't) =
    member this.X = x
    member this.Y = y

let a1 = Vector2D_A(1.0<metre>, 2.0<metre>)
let b1 = Vector2D_A(1.0<metre>, 2.0<metre>)
let c1 = Vector2D_C(1.0<metre>, 2.0<metre>)

let a2 = Vector2D_A(1.0, 2.0) // should produce an error
let b2 = Vector2D_A(1.0, 2.0) // should produce an error
let c2 = Vector2D_C(1.0, 2.0)

      

I would like to define a class as any of these 3 examples (but they don't compile):

1)

type Vector2D_B<'t, [<Measure>] 'u>(x : 't<'u>, y : 't<'u>) =
    member this.X = x
    member this.Y = y

      

2)

type Vector2D_B<'t when 't :> 't<[<Measure>]>>(x : 't<'u>, y : 't<'u>) =
    member this.X = x
    member this.Y = y

      

3)

type Vector2D_B<'t when 't :> 't<_>(x : 't<'u>, y : 't<'u>) =
    member this.X = x
    member this.Y = y

      

+3


source to share


2 answers


The notation 't is equivalent to the notation' t <1> - where <1> is a unit of measure for dimensionless values, which is used implicitly when no other unit is explicitly provided.



Hence, you cannot force the compiler to generate an error message unless you explicitly provide a unit of measure, because when you do, you are implicitly providing a unit for the unitless values.

+3


source


Extend an example from BillH.

Consider a simple case of the multiplication method:

let mult a b = a * b

      

it has a signature (like float)

float<'a> -> float<'b> -> float<'a'b>

      



Now if 'a = 1/'b

, signature

float<'a> -> float<1/'a> -> float<1>

      

Now it is not wise to throw a compiler error for this. For example, a particular call may only occur with a specific set of inputs for some higher order function. As a result, there is no easy way to specify some constraints on a unit that is in some way common (although some of them are possible, such as in the square root function).

Even running a runtime test without a unit given to the function is difficult because the units of information are discarded after the code is compiled.

+3


source







All Articles