我需要能够用F#中的几个不同单位表示相同的概念。例如,我想用光年,天文单位,公里和米表示“距离”。我想使用通用函数来计算这些值。这是我一直LY分组,AU,公里,和m在一起:为什么这个度量单位被限制为1?
[<Measure>] type ly
[<Measure>] type AU
[<Measure>] type km
[<Measure>] type m
[<Measure>] type distance
type UnitValue<[<Measure>] 'u, [<Measure>] 't> =
val conversionFactor : float<'t/'u>
val value : float<'u>
new (v, cf) = { value = FloatWithMeasure<'u> v; conversionFactor = FloatWithMeasure<'t/'u> cf }
member this.toUnits = this.value * this.conversionFactor
member this.fromUnits (x : float<'t>) = x/this.conversionFactor
static member (+) (a : UnitValue<'u, 't>, b : UnitValue<_, 't>) =
a.newValue (a.toUnits + b.toUnits)
static member (-) (a : UnitValue<'u, 't>, b : UnitValue<_, 't>) =
a.newValue (a.toUnits - b.toUnits)
static member (*) (a : UnitValue<'u, 't>, b : float) =
a.newValue (a.toUnits * b)
member this.newValue (x : float<'t>) =
new UnitValue<'u, 't>(float (this.fromUnits x), float this.conversionFactor)
//Distance units
type LightYearValue(value) =
inherit UnitValue<ly, distance>(value, 6324.0)
type AstronomicalUnitValue(value) =
inherit UnitValue<AU, distance>(value, 15.0)
type KilometerValue(value) =
inherit UnitValue<km, distance>(value, 0.00001)
type MeterValue(value) =
inherit UnitValue<m, distance>(value, 0.0000000)
此代码是从单位不知道C#调用,而且可以通过指定new LightYearValue(4.2)
,这将在F#成为UnitValue<ly, distance>
完成,并且可以传递给期望UnitValue<_, distance>
的函数。这样,适当的单位进入功能,并适当的单位出去。例如,如果我通过函数a UnitValue<AU, distance>
,根据计算结果我可能会得到一个float<AU/s^2>
- 并且它将是该比例的适当数字。
感觉与此很高兴,我开始写作的轨道类型:
and Orbit(PeR : UnitValue<_, distance>, ApR : UnitValue<_, distance>, AgP : float, focus : SphericalMass) =
let PeR = PeR
let ApR = ApR
let AgP = AgP
let focus = focus
let Maj = PeR + ApR
let Ecc = (Maj.value - (2.0 * PeR.value))/Maj.value
let DistanceAt theta =
(Maj.value/2.0) * (1.0 - Ecc ** 2.0)/(1.0 + Ecc * Math.Cos(theta))
,但是当我将鼠标悬停我的鼠标PeR
,它说,它的类型是UnitValue<1, distance>
。那么是什么给了?为什么这不起作用?我可以编写一个功能为UnitValue<_, distance>
,它工作正常!它可能与C#与这些代码交互吗? (类型由一个C#类扩展)有什么办法,使这项工作:(
我是那种但是我害怕:/我不想在任何地方宣布单位 – 2011-03-11 14:55:35