开发者

F# units of measure conversion based on type

开发者 https://www.devze.com 2023-01-17 07:47 出处:网络
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

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 o开发者_开发技巧n type when I don't have a obj type.


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

0

精彩评论

暂无评论...
验证码 换一张
取 消