我正在尝试用 F# 编写一个“测量单位”转换器。
我定义了两个测量单位,KWh
和 MWh
,并且我正在尝试编写一个函数来在这两个单位之间进行转换,该函数将在数字类型上进行模式匹配。我可以将浮点型、小数型、整数型 KWh 转换为 MWh。
[<Measure>]
type KWh
[<Measure>]
type MWh
// want to do this, but can't because x is not x:obj,
// its something like x:float<KWh>
let toMWh x =
match x with
| :? float<KWh> -> x * (1.0<MWh>/1000.0<KWh>)
| :? int<KWh> -> // ...
// above code not valid f#
当我没有 obj 类型时,我无法弄清楚如何正确地在类型上分支。
最佳答案
老实说,我只会做低预算的重载解决方案:
[<Measure>]
type KWh
[<Measure>]
type MWh
type Convert =
static member toMWh (x:float<KWh>) = x * 1.0<MWh> / 1000.0<KWh>
static member toMWh (x:int<KWh>) = x * 1<MWh> / 1000<KWh>
printfn "%d" (int(Convert.toMWh(5000<KWh>)))
printfn "%f" (float(Convert.toMWh(5500.0<KWh>)))
也就是说,有人可能会想出一种聪明的、类型安全的方法来使用 inline
来做到这一点(我不确定是否可能)。我会避免你的运行时匹配,因为它牺牲了静态类型安全(这有点是单位的要点)。 (此外,无论如何都不可能进行单元的运行时匹配,因为单元在编译期间被删除。)
关于F# 基于类型的度量单位转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3791959/