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
是否可以这样做?
答案 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!"