如何声明保留计量单位的通用转换运算符?

时间:2017-05-20 13:34:00

标签: f#

F#中的内置转换运算符消除了度量单位。我想定义保存它们的那些。我可以为一个特定的转换做得很好,例如int to float:

let inline intToFloat (x:int<'u>) =
    x |> float |> LanguagePrimitives.FloatWithMeasure<'u>

但我不知道泛型的语法是什么((任何带有op_Implicit ^ m - &gt;浮点数) - &gt;浮点数)运算符:

let inline floatM (x:^m<'u>) =
    x |> float |> LanguagePrimitives.FloatWithMeasure<'u>
// FS0712: Type parameter cannot be used as type constructor

是否可以这样做?

2 个答案:

答案 0 :(得分:1)

解决方法是使用重载而不是泛​​型:

type Conv =
    static member inline toDouble<[<Measure>] 'u> (x: float32<'u>) = 
        x |> float |> LanguagePrimitives.FloatWithMeasure<'u>

    static member inline toDouble<[<Measure>] 'u> (x: sbyte<'u>) = 
        x |> float |> LanguagePrimitives.FloatWithMeasure<'u>

    static member inline toDouble<[<Measure>] 'u> (x: int16<'u>) = 
        x |> float |> LanguagePrimitives.FloatWithMeasure<'u>

    static member inline toDouble<[<Measure>] 'u> (x: int<'u>) = 
        x |> float |> LanguagePrimitives.FloatWithMeasure<'u>

    static member inline toDouble<[<Measure>] 'u> (x: int64<'u>) = 
        x |> float |> LanguagePrimitives.FloatWithMeasure<'u>

现在:

let f = Conv.toDouble (45<second>) // f is a float<second>

我希望能够声明一个操作符来隐藏静态类,例如:

let inline floatM< ^m, [<Measure>]'u when (^m) : (static member toFloat: ^m<'u> -> float<'u>)> (x:^m) =
    Conv.toDouble x

但是,这仍然会遇到同样的限制,即泛型类型不能具有通用的度量单位。

我会接受自己的答案,直到有人找到更好的解决方案。

答案 1 :(得分:0)

我是这样做的:

let inline toIntWithMeasure<[<Measure>] 'a> (x:obj) =
  match x with
  | :? int as i -> i |> LanguagePrimitives.Int32WithMeasure<'a>
  | _ -> failwith "Not an int!"
相关问题