F# 如何声明保留度量单位的通用转换运算符?
F#中的内置转换运算符消除了度量单位。我想定义那些保存它们的。对于一个特定的转换,我可以做得很好,例如int到float:F# 如何声明保留度量单位的通用转换运算符?,f#,F#,F#中的内置转换运算符消除了度量单位。我想定义那些保存它们的。对于一个特定的转换,我可以做得很好,例如int到float: let inline intToFloat (x:int<'u>) = x |> float |> LanguagePrimitives.FloatWithMeasure<'u> 让内联intToFloat(x:int 但我不知道泛型((任何带有op_Implicit ^m->float)->float)运算符的语法是什么:
let inline intToFloat (x:int<'u>) =
x |> float |> LanguagePrimitives.FloatWithMeasure<'u>
让内联intToFloat(x:int
但我不知道泛型((任何带有op_Implicit ^m->float)->float)运算符的语法是什么:
let inline floatM (x:^m<'u>) =
x |> float |> LanguagePrimitives.FloatWithMeasure<'u>
// FS0712: Type parameter cannot be used as type constructor
让内联floatM(x:^m
//FS0712:类型参数不能用作类型构造函数
有可能这样做吗?我就是这样做的:
let inline toIntWithMeasure<[<Measure>] 'a> (x:obj) =
match x with
| :? int as i -> i |> LanguagePrimitives.Int32WithMeasure<'a>
| _ -> failwith "Not an int!"
让内联toIntWithMeasure
|->failwith“Not a int!”
解决方法是使用重载而不是泛型:
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>
type Conv=
静态成员内联(双重)=
x |>float |>LanguagePrimitives.FloatWithMeasure(x:sbyte
静态成员内联(双重)=
x |>float |>LanguagePrimitives.FloatWithMeasure(x:int
静态成员内联(双重)=
x |>float |>language primitives.FloatWithMeasure->float我想答案是否定的,因为F#type系统不能表达更高级的类型。我不再使用度量单位。F#缺少HKT的元原因是很难使用它们。我遇到的一个具体例子是,不久前我尝试用单位来建模货币。这就是在我的库的调用站点上导致了一些严重的代码膨胀,因为我必须为每个单元实例化类型和代码。我当时切换到DU。有一些其他缺点,但毕竟更容易
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