【问题标题】:When should I NOT use Units of Measure?什么时候不应该使用计量单位?
【发布时间】:2016-08-03 20:26:06
【问题描述】:

什么时候不应该使用计量单位?

我觉得计算中使用的任何值都应该有一个计量单位。

我的想法准确吗?

如果是,那么为什么 F# 默认不强制执行此约束以鼓励正确性?

就我而言,我在篮球比赛中使用了度量单位:

例如:

[<Measure>] type pts
type Player = { Score:int<pts> }

这是利用计量单位的模型:

(*Types*)
[<Measure>] type pts
type Player = { Score:int<pts> }

type FieldShot = TwoPointer| ThreePointer
type FoulShots = FoulShot  | TwoFoulShots | ThreeFoulShots

type FoulShooter  = FoulShooter  of Player
type FieldShooter = FieldShooter of Player

(*Functions*)
let shoot (lastShot:int<pts>) player =
    (player.Score + lastShot)

let fieldShot (fieldShooter, shot) =

    let player = match fieldShooter with
                 | FieldShooter player -> player

    match player.Score with
    | score when score > 10<pts> -> score
    | _ ->  match (fieldShooter, shot) with
            | FieldShooter player, shot -> match shot with
                                           | TwoPointer   -> player |> shoot 2<pts>
                                           | ThreePointer -> player |> shoot 3<pts>
let foulShot (foulShooter, shot) =

    let player = match foulShooter with
                 | FoulShooter player -> player

    match player.Score with
    | score when score >= 11<pts> -> score
    | _ ->  match (foulShooter, shot) with
            | FoulShooter player, shot -> match shot with
                                          | FoulShot       -> player |> shoot 1<pts>
                                          | TwoFoulShots   -> player |> shoot 2<pts>
                                          | ThreeFoulShots -> player |> shoot 3<pts>

let makeFoulShots foulShots (shooter, defender) = 
    FieldShooter { Score= foulShot (shooter, foulShots) }, defender

let makeFieldShot fieldBasket (shooter, defender) =
    FoulShooter { Score= fieldShot (shooter, fieldBasket) }, defender

let turnover (shooter, defender) = (defender, shooter)

(*Client*)
let player1, player2 = FieldShooter { Score=0<pts> } ,
                       FieldShooter { Score=0<pts> }

let results = (player1, player2) |> makeFieldShot TwoPointer
                                 |> makeFoulShots ThreeFoulShots
                                 |> makeFieldShot TwoPointer
                                 |> makeFoulShots TwoFoulShots
                                 |> makeFieldShot TwoPointer
                                 |> makeFoulShots FoulShot

【问题讨论】:

  • 我相信在你的情况下使用 UOM 不会给程序带来任何有用的东西,因为你不用不同的单位进行计算。例如,如果您有以 和 表示长度的值,这可能会很有用。
  • 当数字有一些额外的元数据时(例如屏幕/纸张坐标),UOM 可能很有用(在模拟之外)。一件事可能是区分以不同方式得分的分数。但是您总是需要至少两种不同类型的数字,否则您只是在浪费时间
  • 单位也将被删除,因此如果您在运行时互操作或需要它们,那么您就不走运了:运行时的单位测量单位用于静态类型检查。编译浮点值时,会消除测量单位,因此在运行时会丢失单位。因此,任何试图实现依赖于在运行时检查单元的功能都是不可能的。例如,实现 ToString 函数来打印单位是不可能的。
  • 我开始怀疑 F# 是否不是您应该用来学习函数式编程的语言。正如我所指出的,由于使用 .NET 实现并来自 OCaml,F# 的功能受到限制。这不是一件坏事,您只需要在创建解决方案时了解它可以做什么和不能做什么。虽然我不知道 Haskell,但计划,也许你应该学习 Haskell,然后再回到 F#。我认识的许多最优秀的 F# 程序员也知道 Haskell。
  • @ScottNimrod 不,我不认为将度量单位作为预防机制是过度设计的。添加单位几乎没有任何成本 - 请注意,在您的示例中,您可以省略几乎所有的 &lt;pts&gt; 并替换为 &lt;_&gt;。在更真实的代码中,您甚至不会经常看到&lt;_&gt;。我不得不承认,我是度量单位的忠实粉丝(我维护着一个庞大的 F# 代码库),并且单位在无数场合都拯救了这一天。

标签: f# units-of-measurement


【解决方案1】:

好吧,我想到的唯一答案是您通常不应该对dimensionless quantities 使用度量单位。

考虑诸如 pi 或 e 之类的值。

无量纲值通常来自具有某些物理量纲的量的比率。

假设您想创建一些程序逻辑,当一个球队的篮球得分达到另一支球队得分的两倍时触发,您将需要一个无量纲量:

if teamBScore >= 2 * teamAScore then
    ...
else
    ...

2 的值必须用于计算并且必须是无量纲的,否则teamAScore 和teamBScore 的单位将不匹配。

当然,严格来说,您可以使用1 为单位明确地注释这些值,但这可能有点过头了。

除此之外,其余问题主要基于意见。您应该使用或不使用度量​​单位,具体取决于您如何评估以(略微)增加编程时间和冗长为代价获得的安全性收益。

【讨论】:

  • “嗯,我想到的唯一答案是绝对不应该对无量纲量使用计量单位。”确实?不。角度是一个无量纲的量,但这不是不区分度数和弧度(或两者中的无量纲摩尔!)的理由。
  • John Palmer 对这个问题的评论给出了另一个有用地将 UOM 应用于无量纲质量的示例(如果您将屏幕坐标视为像素数而不是长度)。
  • 优点,对于使用度量单位的无量纲数量绝对有效。我认为这仍然是一个不错的指导方针,虽然您可能会使用摩尔作为度量单位,但我认为这将是一个不寻常的步骤,例如千作为一个明确的单位。
【解决方案2】:

如果是,那么为什么 F# 默认不强制执行此约束以鼓励正确性?

一方面,因为它需要与不支持计量单位的语言进行互操作。如果你想在计算中使用来自 C# 库方法的值,它如何决定使用什么单位?即使 F# 开发人员花费大量时间使用度量单位注释所有标准库方法,这对第三方库也无济于事。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-22
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 2011-04-15
    • 2017-04-10
    • 2012-03-19
    相关资源
    最近更新 更多