Generics F中的泛型单位#

Generics F中的泛型单位#,generics,f#,units-of-measurement,Generics,F#,Units Of Measurement,在F#中编写泛型函数时,我可以使用LanguagePrimitives模块中定义的成员,例如在这个函数中,它只是增加一个数字 let inline increment (x : 'a) = x + LanguagePrimitives.GenericOne 我想知道是否有类似于使用度量单位的方法。特别是:是否可以编写一个函数,该函数接受一个泛型参数并将其转换为具有一个单位的相同类型的数。比如: let inline toNumberWithUnit<[<Measure>

在F#中编写泛型函数时,我可以使用LanguagePrimitives模块中定义的成员,例如在这个函数中,它只是增加一个数字

let inline increment (x : 'a) =
    x + LanguagePrimitives.GenericOne
我想知道是否有类似于使用度量单位的方法。特别是:是否可以编写一个函数,该函数接受一个泛型参数并将其转换为具有一个单位的相同类型的数。比如:

let inline toNumberWithUnit<[<Measure>] 'u> x =
    x * GenericOne<'u> //that won't work
让内联的toNumberWithUnit//这样不行

这将有一个类型:'a->'a,该签名在.NET中是非法的,因此唯一的方法是使用带有静态约束的F#inline特性

然后您可以定义如下函数:

[<Measure>]
type M = class end

let x = LanguagePrimitives.FloatWithMeasure<M> 2. 

type T<[<Measure>]'M>() =
    static member ($) (T, x) = LanguagePrimitives.FloatWithMeasure<'M> x
    static member ($) (T, x) = LanguagePrimitives.Float32WithMeasure<'M> x
    static member ($) (T, x) = LanguagePrimitives.Int32WithMeasure<'M> x
    // more overloads

let inline NumberWithMeasure x = T() $ x

let a: float<M>   = NumberWithMeasure 2.
let b: float32<M> = NumberWithMeasure 2.0f
let c: int<M>     = NumberWithMeasure 2
可能有一种方法可以创建泛型函数或泛型常量,但目前在当前版本的F#中似乎不可能


当F#4.1准备就绪时,我将尝试使用它。

因此,我不能有一个通用函数,而是一系列函数,需要明确我要使用哪一个。好吧,仍然不是我想要的,但正如你所说的,这是我目前能得到的最好的,这一定足够了。非常感谢,先生:)。
[<Measure>] type km
[<Measure>] type miles

type WithMeasure<[<Measure>]'M>() =
    static member ($) (x, T) = LanguagePrimitives.FloatWithMeasure<'M> x
    static member ($) (x, T) = LanguagePrimitives.Float32WithMeasure<'M> x
    static member ($) (x, T) = LanguagePrimitives.Int32WithMeasure<'M> x
    static member ($) (x, T) = LanguagePrimitives.DecimalWithMeasure<'M> x
    static member ($) (x, T) = LanguagePrimitives.Int16WithMeasure<'M> x
    static member ($) (x, T) = LanguagePrimitives.Int64WithMeasure<'M> x
    static member ($) (x, T) = LanguagePrimitives.SByteWithMeasure<'M> x
    // no more overloads


let a: float<km>      = 2.   $WithMeasure()
let b: float32<miles> = 2.0f $WithMeasure()