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

When should I NOT use Units of Measure?

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

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

我的想法准确吗?

如果是,那么为什么 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

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

考虑 pi 或 e.

等值

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

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

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

2 必须用于计算并且必须是无量纲的,否则 teamAScoreteamBScore 的单位不匹配。

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

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

If they are, then why doesn't F# by default enforce this constraint to encourage correctness?

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