2014-10-08 141 views
3

如何在F#中创建泛型类,约束条件是类型是度量?具有度量约束的泛型类

我已经试过,但A2和B2不产生错误:

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) 

我想定义就像任何的这三个例子类(但不进行编译):

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

书写“t是相当于写入” T < 1> - ,其中< 1>表示的计量单位为无量纲值,其隐式应用被明确地提供测量的任何其他单元时。

因此,当您没有明确提供度量单位时,您不能强制编译器生成错误消息,因为当您这样做时,隐式提供无量纲值的度量单位。

3

扩展BillH的例子。

考虑乘法方法的简单情况:的

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

let mult a b = a * b 

这有一个签名(比如浮动)现在,如果'a = 1/'b签名

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

现在抛出编译器错误是不合理的。例如,特定的调用只能通过一些特定的输入到一些更高阶的函数来进行。因此,没有简单的方法来指定某些通用的计量单位的某些约束条件(尽管有些可能在例如平方根函数中)。

即使对给定函数的单位执行运行时测试也很难,因为在编译代码后,度量单位信息会被丢弃。