F# 基于类型的度量单位转换

标签 f# units-of-measurement

我正在尝试用 F# 编写一个“测量单位”转换器。

我定义了两个测量单位,KWhMWh,并且我正在尝试编写一个函数来在这两个单位之间进行转换,该函数将在数字类型上进行模式匹配。我可以将浮点型、小数型、整数型 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/

相关文章:

assembly - 在 F# 中获取引用的程序集

css - CSS rem 单位有多精细?

java - 打印 JScience 中所有定义的单位

visual-c++ - D3D12 CreateHeap 对齐,MSDN 使用 1024 还是 1000 来定义 KB

f# - 在 F# 中查找最大值、最小值和平均值

data-structures - F# 有效地从 Set 的末尾删除 n 个项目

silverlight - 在 Windows Phone 上使用 F# sprintf "%A"时出现反射错误

c# - F# OOP - 实现接口(interface) - 私有(private)和方法名称问题

scala - 是否可以在 Scala 中为度量单位实现 F# 的基础结构?

c# - 为什么 NumberFormatInfo 中包含货币而不是其他单位