具有度量约束的泛型类

时间:2014-10-08 21:21:24

标签: f# generic-programming

如何在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

2 个答案:

答案 0 :(得分:3)

写't等同于写't&lt; 1&gt; - 其中&lt; 1&gt;表示无量纲值的度量单位,在没有明确提供其他度量单位时隐式应用。

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

答案 1 :(得分:3)

扩展BillH的例子。

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

let mult a b = a * b

这有

的签名(比如浮动)
float<'a> -> float<'b> -> float<'a'b>

现在,如果'a = 1/'b签名是

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

现在抛出编译器错误是不合理的。例如,特定调用只能在某些高阶函数的特定输入集合中发生。因此,没有简单的方法来指定一些度量单位的约束,这些约束在某种程度上是通用的(尽管有些可能在例如平方根函数中)。

即使对函数赋予了没有单位的运行时测试也很难,因为在编译代码之后会丢弃度量单位信息。