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有一篇研究论文。我猜测它不仅仅是几行代码来实现整个事情。夏天项目有人吗? :)
答案 0 :(得分:11)
以新类型换行数字并为其提供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
答案 1 :(得分:7)
dimensional和dimensional-tf(使用类型系列而不是多参数类型类)库非常好,可以处理示例中提供的大多数问题。
我不认为图书馆允许您定义像货币这样的自定义尺寸。据我所知,你需要修改库代码才能做到这一点。
答案 2 :(得分:4)
行。我知道这个问题太老了。但是,有一个GHC插件构建来提供Haskell中的度量单位功能。请参阅这个Adam Gundry的paper。
答案 3 :(得分:1)
units包似乎很有希望并且允许在相同维度的不同单元之间进行转换。但是,我没有使用它,我不知道它是否稳定。公平地说,我今天尝试安装它并且安装失败了......
答案 4 :(得分:1)
首先查看haskell.org wikipage关于在Haskell中强制执行单位的信息:
https://wiki.haskell.org/Physical_units
有多种选择,但我不确定是否确实存在类似于&#34;测量单位&#34;你提到过。
答案 5 :(得分:0)
虽然我对学习感兴趣并且仍然对F#感兴趣,但我并不了解Haskell,但是,似乎一般的解决方案应该是将度量视为标量元组和代表单元的标签,( N,M)。
例如,让measure为measure<N,M>
的通用元组,其中N
是数字而M
是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
....