gpt4 book ai didi

.net - 带有度量单位的重载函数

转载 作者:行者123 更新时间:2023-12-02 03:25:00 24 4
gpt4 key购买 nike

TL;DR 我如何编写一个“重载”函数来处理所有具有单位的数字类型具有相同单位的单独类型(float32<m> -> Vector2<m>int<kg> -> Vector2<kg> )?

我有一个不错的小 Vector2 类,但我想允许将度量单位附加到它,所以我基本上是这样定义它的(但功能比这里包含的要多得多):

type Vector2<[<Measure>] 'u>(x: float32<'u>, y: float32<'u>) =
member this.X = x
member this.Y = y

我也能够轻而易举地编写重载算术运算符(例如 static member (+) ... ),但我一直在努力编写可以处理所有数字类型的构造函数运算符(称为 @@ )以及单位(允许我写 1<m> @@ 2.5<m> 而不是 new Vector2<m>(1.<m>, 2.<m>) 。在我将单位附加到这个类之前,它真的很容易:

let inline (@@) x y = new Vector2(float32 x, float32 y)

到目前为止,我已经编写了一个辅助类来处理这个问题:

type OverloadedOperators =
static member CreateVector2 (x: float32<'u>, y: float32<'u>) = new Vector2<'u>(x, y)
static member CreateVector2 (x: float<'u>, y: float<'u>) = new Vector2<'u>(x |> float32 |> Float32WithMeasure<'u>, y |> float32 |> Float32WithMeasure<'u>)
static member CreateVector2 (x: int<'u>, y: int<'u>) = new Vector2<'u>(x |> float32 |> Float32WithMeasure<'u>, y |> float32 |> Float32WithMeasure<'u>)

但似乎不可能编写适当的类型约束来处理这种调用情况。例如,这样的事情是行不通的

let inline (@@) (x: 'u when 'u : (static member CreateVector2 : 'u * 'u -> Vector2<'v>)) y = OverloadedOperators.CreateVector2 (x, y)

因为The type 'u is not compatible with float32<'v> , The type 'u is not compatible with int<'v> , ETC。我不确定如何写这最后的一小段。我想要的有可能吗?或者我应该忍受不断使用 Vector2到处都是构造函数?

编辑 感谢@JohnPalmer,我已经非常接近了,我在他的回答的基础上想出了最后一点:let inline vec2 p = convert *** p .现在最后一步是“取消元组”这个函数,让它成为一个中缀运算符,但这似乎是不可能的,因为它一开始甚至不知道它总是一个元组。我想我可能已经尽可能地使用 F#,但如果我错了请纠正我!与此同时,我将解决 vec2 (10.<m>, 20.<m>) ,这比我每次调用构造函数时都必须内联执行所有困惑的单元类型转换要好很多

最佳答案

这是一个稍微有点老套的解决方案,它是根据我们在这种情况下使用的标准技巧构建的:

open LanguagePrimitives
type Vector2<[<Measure>] 'u>(x: float32<'u>, y: float32<'u>) =
member this.X = x
member this.Y = y
type OverloadedOperators() =
static member CreateVector2 (x: float32<'u>, y: float32<'u>) = new Vector2<'u>(x, y)
static member CreateVector2 (x: float<'u>, y: float<'u>) = new Vector2<'u>(x |> float32 |> Float32WithMeasure<'u>, y |> float32 |> Float32WithMeasure<'u>)
static member CreateVector2 (x: int<'u>, y: int<'u>) = new Vector2<'u>(x |> float32 |> Float32WithMeasure<'u>, y |> float32 |> Float32WithMeasure<'u>)
static member ( *** ) (T,(x:float32<'u>,y)) = OverloadedOperators.CreateVector2(x,y)
static member ( *** ) (T,(x:float<'u>,y)) = OverloadedOperators.CreateVector2(x,y)
static member ( *** ) (T,(x:int<'u>,y)) = OverloadedOperators.CreateVector2(x,y)
let convert =OverloadedOperators()

(* testing *)
[<Measure>]
type m

convert *** (1<m>,1<m>)
convert *** (1.0<m>,1.0<m>)

它使用两个运算符并且过于冗长,但相当接近您想要的

关于.net - 带有度量单位的重载函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30905649/

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