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

发布于 2024-09-25 00:52:25 字数 550 浏览 4 评论 0原文

我正在尝试用 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 类型时,我无法弄清楚如何正确地在类型上分支。

I'm trying to write a "unit of measure" converter in F#.

I have defined two units of measure, KWh and MWh and I am trying to write a function to convert between the two that will pattern match on the numeric type. I could have a float, decimal, int of KWh to convert to 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#

I'm not able to figure out how to correctly branch on type when I don't have a obj type.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

七禾 2024-10-02 00:52:26

老实说,我只想做低预算重载解决方案:

[<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 来做到这一点(我不确定它是否是临时的)可能的)。我会避免你的运行时匹配,因为它牺牲了静态类型安全(这有点是单位的要点)。 (此外,无论如何都不可能进行单元的运行时匹配,因为单元在编译期间被擦除。)

Honestly, I'd just do the low-budget overloading solution:

[<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>)))

That said, someone may come up with a clever, type-safe way to do it with inline (I'm not sure offhand if it's possible). I would avoid your run-time matching, since it sacrifices static type-safety (which is kinda the point of units). (Also, it is impossible to do run-time matching of units anyway, since units are erased during compilation.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文