繁体   English   中英

是否有一个Haskell等价的F#度量单位?

[英]Is there a Haskell equivalent of F# units of measure?

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上有一篇研究论文。 我猜测实现整个过程不仅仅是几行代码。 夏天项目有人吗? :)

在newtype中包装数字并为它们提供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

维度维度-tf (使用类型系列而不是多参数类型类)库非常好,可以处理示例中提供的大多数问题。

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

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

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

请先查看haskell.org wikipage,了解有关在Haskell中强制执行单元的信息:

https://wiki.haskell.org/Physical_units

有多种选择,但我不确定是否确实存在类似于您提到的“计量单位”的内容。

我不太了解Haskell虽然我对学习感兴趣并且仍然使用F#,但是,似乎一般的解决方案应该是将度量视为标量元组和表示单位的标签(N,M)。

例如,让measure为measure<N,M>的通用元组,其中N是数字, Mstring ,则=, +, -, *, /, ^可以重载以实现对给定度量的评估, 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
....

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM