Когда НЕ следует использовать единицы измерения?

Когда НЕ следует использовать единицы измерения?

Я считаю, что к любым значениям, которые используются в расчетах, должна применяться единица измерения.

Верны ли мои мысли?

Если да, то почему 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

person Scott Nimrod    schedule 13.04.2016    source источник
comment
Я считаю, что в вашем случае использование UOM не приносит ничего полезного в программу, потому что вы не делаете расчеты с разными единицами измерения. Это может быть полезно, если у вас есть значения, представляющие длину, например, в ‹inches› и ‹centimeters›.   -  person Petr    schedule 13.04.2016
comment
Было бы чрезмерным инженерией, если бы я использовал UOM в качестве механизма предотвращения ошибок обслуживания, если бы программу нужно было расширить? Или применяется ЯГНИ?   -  person Scott Nimrod    schedule 13.04.2016
comment
Не знаю, что такое ЯГНИ, но да, я считаю, что это было бы излишним   -  person Petr    schedule 13.04.2016
comment
Вам это не понадобится   -  person Scott Nimrod    schedule 13.04.2016
comment
Единицы измерения могут быть полезны (вне моделирования), когда числа имеют некоторые дополнительные метаданные, например координаты экрана / бумаги. Одно дело - различать очки, набранные по-разному. Но вам всегда нужны как минимум два разных типа чисел, или вы просто зря теряете время.   -  person John Palmer    schedule 13.04.2016
comment
единицы также будут удалены, поэтому, если вы взаимодействуете или нуждаетесь в них во время выполнения, вам не повезло: единицы во время выполнения. Единицы измерения используются для проверки статического типа. При компиляции значений с плавающей запятой единицы измерения удаляются, поэтому единицы теряются во время выполнения. Следовательно, любая попытка реализовать функциональность, зависящую от проверки модулей во время выполнения, невозможна. Например, реализация функции ToString для распечатки единиц невозможна.   -  person s952163    schedule 13.04.2016
comment
Я начинаю задаваться вопросом, не является ли F # тем языком, который вы должны использовать для изучения функционального программирования. Как я уже отмечал, возможности F # ограничены, поскольку он реализован с помощью .NET и исходит от OCaml. Это неплохая вещь, вам просто нужно знать, что можно и чего нельзя делать при создании решений. Хотя я не знаю Haskell, но планирую, возможно, вам стоит изучить Haskell, а затем вернуться к F #. Многие из лучших программистов на F #, которых я знаю, также знают Haskell.   -  person Guy Coder    schedule 13.04.2016
comment
Я зашел слишком далеко, чтобы покинуть корабль. Следовательно, я тратил слишком много своего свободного времени на эту технологию. Таким образом, я полагаю, что у меня есть еще шесть месяцев, пока я не стану компетентным в F #. Как только я освоюсь с F #, я посещу Scala.   -  person Scott Nimrod    schedule 13.04.2016
comment
@ScottNimrod Нет, я не считаю, что использование единиц измерения в качестве профилактического механизма было бы чрезмерной инженерией. Добавление единиц почти ничего не стоит - обратите внимание, что в вашем примере вы могли бы почти полностью опустить <pts> и заменить на <_>. В более реалистичном коде вы даже не будете часто видеть <_>. Я должен признать, что я большой поклонник единиц измерения (я поддерживаю огромную базу кода F #), и единицы спасали положение в бесчисленных случаях.   -  person Anton Schwaighofer    schedule 13.04.2016


Ответы (2)


Если да, то почему F # по умолчанию не применяет это ограничение для поощрения правильности?

Во-первых, потому что он должен взаимодействовать с языками, которые не поддерживают единицы измерения. Если вы хотите использовать в вычислениях значения, поступающие из библиотечного метода C #, как он может решить, какую единицу использовать? Даже если разработчики F # потратят много времени на аннотирование всех стандартных библиотечных методов с помощью единиц измерения, это не поможет со сторонними библиотеками.

person Alexey Romanov    schedule 13.04.2016

Что ж, единственный ответ, который приходит на ум, заключается в том, что вам обычно не следует использовать единицы измерения для безразмерных величин.

Рассмотрим такие значения, как пи или e.

Безразмерные значения часто возникают из соотношений величин, которые действительно имеют какое-то физическое измерение.

Предположим, вы хотите создать некоторую программную логику, которая срабатывает, когда счет баскетбольного мяча одной команды достигает удвоенного счета другой команды, вам понадобится безразмерная величина:

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

Значение 2 должно использоваться в вычислениях и должно быть безразмерным, иначе единицы teamAScore и teamBScore не будут совпадать.

Конечно, строго говоря, вы могли бы явно аннотировать такие значения с помощью единиц 1, но это, вероятно, излишне.

Кроме того, остальная часть вопроса в первую очередь основана на мнении. Вам следует использовать или не использовать единицы измерения в зависимости от того, как вы оцениваете повышение безопасности, которое вы получите за счет (немного) увеличения времени программирования и многословия.

person TheInnerLight    schedule 13.04.2016
comment
Что ж, единственный ответ, который приходит на ум, это то, что вам определенно не следует использовать единицу измерения для безразмерных величин. Определенно? Нет. Угол - это безразмерная величина, но это не причина не различать градусы и радианы (или также безразмерные моль от любого из них!). - person Alexey Romanov; 13.04.2016
comment
Комментарий Джона Палмера к этому вопросу дает еще один пример полезного применения единиц измерения к безразмерным качествам (если вы рассматриваете координаты экрана как количество пикселей, а не длину). - person Alexey Romanov; 13.04.2016
comment
Хорошие моменты, определенно допустимые варианты использования безразмерных величин с использованием единиц измерения. Я думаю, что это остается достойным ориентиром, хотя вы можете использовать родинки в качестве единицы измерения, я думаю, что это будет необычный шаг для использования, например тысячи как явная единица. - person TheInnerLight; 13.04.2016