使用F#测量单位从m/s转换为km/h

Jon*_*esø 8 f# units-of-measurement

我正在学习F# - 目前正在研究测量单位.我有一个简单的计算返回米每秒,我想引入一个函数将其转换为每小时公里.

我的代码看起来像这样:

[<Measure>] type kg
[<Measure>] type s
[<Measure>] type m
[<Measure>] type km
[<Measure>] type h            

let msToKmph(speed : float<m/s>) =
    (float speed) * 3.6<km/h>

let gravityOnEarth = 9.81<m/s^2>
let heightOfJump = 3.5<m>

let speedOfImpact = sqrt (2.0 * gravityOnEarth * heightOfJump)
let speedOfImpactKmh = msToKmph(speedOfImpact)
Run Code Online (Sandbox Code Playgroud)

这是有效的 - 我得到8.28673639 m/s和29.832251 km/h.我不确定的是,这是表达不同单位之间关系的最佳方式.这可以更优雅地完成吗?

例如,行(浮动速度)从速度参数中移除单位信息,使msToKmph返回km/h.如果我在进行计算之前没有删除单位信息,则返回的单位为:km m /(hs)

byt*_*ter 17

首先,你msToKmph完全不正确.虽然它返回一个正确的返回值,它实际上是在做什么,它只是降低了原来<m/s>通过转换为普通,价值无量 float,然后乘以无量价值的3.6<km/h>.

为了更好地表达UoM之间的关系,请考虑以下事项:

let kmToM = 1000.0<m/km>  // relation between kilometers and meters
let hrToSec = 3600.0<s/h> // relation between seconds and hours
let msToKmph(speed : float<m/s>) =
    speed / kmToM * hrToSec
Run Code Online (Sandbox Code Playgroud)

请注意,所有"幻数"都封装在UoM转换器中,因此您的公式保持干净,例如它们只是操作值和常量,但UoM由编译器计算.

更新: UoM转换的理念是转换公式应该是具有物理意义的东西.经验法则是您的转换价值是否出现在参考书中.用简单的英语,3.6<km/h>从上面来说是没用的,但1000.0<m/km>只是说,"1公里内有1000米",这是有道理的.

你甚至可以hrToSec像这样改进:

let hrToSec2 = 60.0<s/minute> * 60.0<minute/h>
Run Code Online (Sandbox Code Playgroud)

这将使每个价值成为参考书中的众所周知的价值.