【发布时间】:2014-02-27 14:24:39
【问题描述】:
F# 有一个units of measure capability(research paper 中有更多详细信息)。
[<Measure>] type unit-name [ = measure ]
这允许定义单位,例如:
type [<Measure>] USD
type [<Measure>] EUR
而代码要写成:
let dollars = 25.0<USD>
let euros = 25.0<EUR>
// Results in an error as the units differ
if dollars > euros then printfn "Greater!"
它还处理转换(我猜这意味着 Measure 定义了一些函数,可以让Measures 进行乘法、除法和求幂):
// Mass, grams.
[<Measure>] type g
// Mass, kilograms.
[<Measure>] type kg
let gramsPerKilogram : float<g kg^-1> = 1000.0<g/kg>
let convertGramsToKilograms (x : float<g>) = x / gramsPerKilogram
这个功能可以在 OCaml 中实现吗?有人建议我查看幻象类型,但它们的组成方式似乎与单位不同。
(披露:几个月前我问过这个关于 Haskell 的问题,得到了一个有趣的讨论,但除了“可能不是”之外没有明确的答案。
【问题讨论】:
-
我对您的建议也是幻像类型,但您是正确的,它们不会按照您的意愿“组合”。您提到的第一种情况(比较错误)和最后一种情况(转换函数)可以由幻像类型处理。
-
在每种语言中使用它来做任何可以远程物理解释的事情真的很有意义......!
-
这可以作为类型检查器级别的插件。有一些关于允许类型检查器插件的讨论。在这种情况下,我不知道编译器的当前状态是什么。
-
为 OCaml 提供编译时度量单位支持似乎是个好主意,顺便说一句,我创建了一个 F# 运行时度量单位库,您可以轻松移植并可能使用它来获得一些灵感:trelford.com/blog/post/Runtime-Units-of-Measure-for-F.aspx
-
您可以为这些类型编写组合函数(例如,具有
type ('a,'b) per和type 'a measure = { v : float };和let (</>) (a : 'a measure) (b : 'b measure) : (('a,'b) per) measure = {a.v /. b.v}但您会遇到乘法和关联性问题,我假设 F# 会处理这些问题。
标签: f# ocaml units-of-measurement