如何在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
答案 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>
现在抛出编译器错误是不合理的。例如,特定调用只能在某些高阶函数的特定输入集合中发生。因此,没有简单的方法来指定一些度量单位的约束,这些约束在某种程度上是通用的(尽管有些可能在例如平方根函数中)。
即使对函数赋予了没有单位的运行时测试也很难,因为在编译代码之后会丢弃度量单位信息。