gpt4 book ai didi

f# - 为什么这个度量单位被限制为 1?

转载 作者:行者123 更新时间:2023-12-04 06:32:08 24 4
gpt4 key购买 nike

我需要能够用 F# 中的几个不同单位来表示相同的概念。例如,我想用光年、天文单位、公里和米来表示“距离”。我想使用通用函数对这些值进行计算。这就是我将 ly、AU、km 和 m 组合在一起的方式:

[<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) 即可完成, 这将成为 UnitValue<ly, distance>在 F# 中,并且可以传递给期望 UnitValue<_, distance> 的函数.这样,适当的单元进入函数,适当的单元退出。例如,如果我将函数传递给 UnitValue<AU, distance> ,我可能会得到一个 float<AU / s ^ 2>取决于计算 - 这将是规模的适当数字。

对此感到非常满意,我开始编写 Orbit 类型:
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# 类扩展)有什么办法可以使这项工作:(

最佳答案

声明类型时,需要显式声明泛型类型参数(以及单元参数)。以下声明正确地推断出类型:

type Orbit<[<Measure>] 'u, [<Measure>] 'v> 
( PeR : UnitValue<'u, distance>, ApR : UnitValue<'v, distance>,
AgP : float, focus : SphericalMass) =
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))

(顺便说一句:您不需要为本地 let 绑定(bind)重新分配参数 - 它们将可以自动访问,所以我删除了像 let ApR = ApR 这样的行)

关于f# - 为什么这个度量单位被限制为 1?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5269881/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com