Единица измерения "Тип" в F # - PullRequest
1 голос
/ 07 декабря 2010

Я пишу функцию преобразования для единиц измерения в F #.Информация о значениях поступает из веб-приложения ASP.NET.

Функция, которую я создаю, определяется следующим образом:

let convert (x:float<_>) (toType : string) =
  // Do conversion here.

Первая проблема, с которой я сталкиваюсь, связана с toType.: определение строки.Можно ли как-то определить, чтобы он принимал тип float<_> ... особенно из веб-приложения?(Я знаю, что это часть CLR, основанная на превосходных статьях Эндрю Кеннеди , но я не понимаю, как в общем случае определить ее в функции.

Спасибо за любую помощь, которую вы можете предоставить.

Ответы [ 2 ]

2 голосов
/ 07 декабря 2010

Если вы просто хотите иметь возможность читать в «2,0 фута» и «5,0 м», тогда

  • вы должны написать код, который анализирует строки и выполняет некоторую условную логику (например,если «фут», то превращается в float<ft> или что-либо еще)

  • , как только вы преобразуете данные в систему типа F #, вы можете делать что-то безопасным образом

Это типично для каждого приложения, которое хочет получать строго типизированные данные из внешнего мира;есть компонент ввода, который должен анализировать и проверять ввод и сохранять его в строго типизированной структуре данных, но затем программа может использовать эти данные впредь.

(В любой библиотеке нет волшебного анализатора / средства проверки вводаВы просто делаете это для своих типов данных.)

2 голосов
/ 07 декабря 2010

Я не думаю, что будет возможно делать то, что вы хотите, так как типы мер стираются во время выполнения. В частности, нет ничего похожего на проверку типов во время выполнения (например, оператор F # (:?)) Для типов показателей.

Какую логику вы хотели реализовать в своей convert функции?

UPDATE

Исходя из предоставленной вами дополнительной информации, вот еще несколько мыслей:

  1. Весь смысл единиц измерения F # состоит в том, чтобы во время компиляции обеспечить использование величин, соответствующих единицам измерения. Это означает, что вы не можете написать функцию convert : float<'t> -> float<'u> - что произойдет, если ваши пользователи попытаются выполнить бессмысленное преобразование (например, преобразование чего-либо из float<kg> в float<m/s^2>)? Задача типов единиц F # состоит в том, чтобы статически предотвращать подобные преобразования.

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

    [<Measure>] type m
    [<Measure>] type km
    
    
    let convert (f:float) (s:string) : float<m> =
      match s with
      | "m" -> f * 1.0<m>
      | "km" -> f * 1.0<km> * 1000.0<km/m>
      | _ -> failwith (s |> sprintf "Unknown unit of measure: %s")
    

    Всегда возвращает результат в метрах, основанный на количестве единиц и названии единиц, которые он представляет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...