【问题标题】:Converting from m/s to km/h using F# Units of Measure使用 F# 测量单位从 m/s 转换为 km/h
【发布时间】:2012-11-29 02:42:24
【问题描述】:

我正在学习 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)

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

例如,行(浮动速度)从速度参数中删除单位信息,以使 msToKmph 返回 km/h。如果我在计算之前没有删除单位信息,返回的单位是:km m/(h s)

【问题讨论】:

  • 您可能希望将此发布到 CodeReview 堆栈交换。 codereview.stackexchange.com 除此之外,我认为您的方法很好。
  • 我自己没有使用过它们,但我会使用适当的单位(例如let mToKm(length: float&lt;m&gt;) = length * 0.001&lt;km/m&gt;)表示的比率定义相同“类型”(例如长度)的单位之间的转换函数,然后基于这些简单的转化建立其他转化。

标签: f# units-of-measurement


【解决方案1】:

首先,您的msToKmph 完全不正确。虽然它返回一个正确的返回值,但它实际上在做什么,它只是 drops 原来的 &lt;m/s&gt; 值通过转换为一个普通的 measureless float 然后将 measureless 值乘以 3.6&lt;km/h&gt;

为了更好地表达计量单位之间的关系,请考虑以下几点:

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

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

更新:计量单位转换的理念是转换公式应该是具有物理意义的东西。经验法则是您的转化价值是否出现在参考书中。用简单的英语,上面的3.6&lt;km/h&gt; 是没用的,但1000.0&lt;m/km&gt; 只是说,“1 km 有 1000 m”,这是有道理的。

你甚至可以像这样改进hrToSec

let hrToSec2 = 60.0<s/minute> * 60.0<minute/h>

这将使每个值都成为参考书中的知名值。

【讨论】:

    【解决方案2】:

    您说得对,删除单位信息是一件坏事。您应该创建一些具有适当单位的常量以进行转换。

    let mPerKm = 1000.0<m/km>
    let secondPerHour = 3600.0<s/h>
    
    // val msToKmph : float<m/s> -> float<km/h>
    let msToKmph(speed : float<m/s>) =
        speed / mPerKm * secondPerHour
    

    对于kmm,一个通用的解决方案是定义一个单位前缀k,以便它适用于许多以公斤为度量单位的计量单位:

    [<Measure>] type k
    
    let kilo = 1000.0<1/k>
    let secondPerHour = 3600.0<s/h>
    
    // val msToKmph : float<m/s> -> float<k m/h>
    let msToKmph(speed : float<m/s>) =
        speed / kilo * secondPerHour
    

    【讨论】:

    • 从未想过公斤,整洁的想法。不过我会打电话给hourPerSecondsecondPerHour
    • kilo 是个好主意,我不久前就在考虑。我被困在像km^2 这样的复合值上,结果是kilo^2 * m^2。对于典型的 SI UoM 来说这不是问题,但对于实际计算来说可能会很痛苦。一般来说,您如何建议减轻这种情况?
    • @bytebuster:你是对的。这是km 看起来比k m 更好的地方。我不知道有什么方法可以绕过这个。
    猜你喜欢
    • 2020-02-14
    • 1970-01-01
    • 1970-01-01
    • 2020-05-09
    • 2021-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-07
    相关资源
    最近更新 更多