15

F# 具有度量单位功能,在http://msdn.microsoft.com/en-us/library/dd233243.aspx中描述如下:

[<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

我的直觉告诉我应该可以在 Haskell 中实现类似的功能,但我无法找到任何示例来说明如何做到这一点。

编辑:哦,我的话,这是一个巨大的蠕虫罐头!http://research.microsoft.com/en-us/um/people/akenn/units/CEFP09TypesForUnitsOfMeasure.pdf上有一篇研究论文。我猜想实现整个事情不仅仅是几行代码。夏季项目有人吗?:)

4

6 回答 6

12

将数字包装在一个新类型中并给它们一个Num实例。

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

newtype GBP n = GBP n deriving (Show, Num, Eq, Ord)
newtype USD n = USD n deriving (Show, Num, Eq, Ord)

用法:

ghci> let a1 = GBP 2
ghci> let a2 = GBP 5
ghci> a1 + a2
GBP 7
ghci> let b1 = USD 3
ghci> let b2 = USD 6
ghci> b1 + b2
USD 9
ghci> a1 + b2 -- should be an error for mixing currencies

<interactive>:8:6:
    Couldn't match expected type `GBP Integer'
                with actual type `USD Integer'
    In the second argument of `(+)', namely `b2'
    In the expression: a1 + b2
    In an equation for `it': it = a1 + b2
于 2013-06-11T15:48:06.443 回答
7

DimensionDimension-tf (使用类型族而不是多参数类型类)库非常好,可以处理示例中出现的大多数问题。

不过,我认为该库不允许您定义货币等自定义维度。据我所知,您需要修改库代码才能做到这一点。

于 2013-06-12T17:15:14.870 回答
4

好的。我知道这个问题太老了。但是,有一个 GHC 插件构建可以在 Haskell 中提供度量单位功能。请参阅此 Adam Gundry 的论文

于 2015-08-27T19:53:46.310 回答
1

单位包似乎很有前途,并允许在相同维度的不同单位之间进行转换。但是,我没有使用它,我不知道它是否稳定。公平地说,我今天尝试安装它,但安装失败......

于 2014-07-07T14:29:48.340 回答
1

首先查看 haskell.org wikipage 关于在 Haskell 中执行单元的信息:

https://wiki.haskell.org/Physical_units

有多种选择,但我不确定是否真的有类似于你提到的“计量单位”的东西。

于 2015-03-17T07:42:18.310 回答
0

我对 Haskell 了解不多,虽然我对学习很感兴趣,而且对 F# 还很初级,但是,似乎一个通用的解决方案应该是将度量视为一个标量元组和一个代表单位的标签,(N,M)。

例如,让 measure 是 的一个通用元组measure<N,M>,其中N是一个数字,M是 a string,那么=, +, -, *, /, ^可以重载以实现对给定度量 、a, b, and c、标量p、布尔 k 和度量标签规范化函数的评估,norm使得

a = b = (Na,Ma) = (Nb,Mb) = (Na = Nb) and norm(Ma) = norm(Mb) = k
a + b = (Na,Ma) + (Nb,Mb) = (Na + Nb, Ma) = c provided norm(Ma) = norm(Mb)
a * b = (Na,Ma) * (Nb,Mb) = (Na * Nb, Ma * Mb) = c
a ^ p = (Na,Ma) ^ p       = (Na ^ p , Ma ^ p ) = c
....
于 2015-09-27T11:05:02.303 回答