F# 类型扩展与测量单位类型转换导致奇怪的错误

发布于 2024-12-17 11:47:52 字数 1079 浏览 1 评论 0原文

我有一个函数,可以从我自己的 3D 矢量实现(支持测量单位)转换为 XNA 的实现:

type Vector3<[<Measure>]'a> with
    member inline v.ToXna() =
        Microsoft.Xna.Framework.Vector3(v.x / 1.f<_>, v.y / 1.f<_>, v.z / 1.f<_>)

当我编译它时,我收到一个奇怪的错误:

签名和实现不兼容,因为类型 类/签名中的参数具有不同的编译时 对成员/实施中的要求

inline 似乎是必要的;如果没有它,我会收到此错误:

此构造导致代码不如所示的通用 类型注释。计量单位变量 'a 已受到约束 以“m”为单位。

知道发生了什么事吗?

编辑为了回答@svick的问题,Vector3被定义为:

type Vector3<[<Measure>]'u> =
    struct
        val x:float32<'u>
        val y:float32<'u>
        val z:float32<'u>
        new(x, y, z) = { x = x; y = y; z = z }
    end

并且我在将其定义为普通函数时也遇到了一些类型推断问题:

let vector3 (v:DumpEngine.Vector3<_>) =
    Vector3(v.x / 1.f<_>, v.y / 1.f<_>, v.z / 1.f<_>)

导致该函数成为Vector3<1>; -> Microsoft.Xna.Framework.Vector3,这使得它非常无法使用。不过,我不确定这是一个相关问题。

I have a function that converts from my own implementation of a 3D vector (which supports units of measure) to XNA's implementation:

type Vector3<[<Measure>]'a> with
    member inline v.ToXna() =
        Microsoft.Xna.Framework.Vector3(v.x / 1.f<_>, v.y / 1.f<_>, v.z / 1.f<_>)

When I compile it, I get a strange error:

The signature and implementation are not compatible because the type
parameter in the class/signature has a different compile-time
requirement to the one in the member/implementation

The inline seems to be a necessity; without it, I get this error:

This construct causes code to be less generic than indicated by the
type annotations. The unit-of-measure variable 'a has been constrained
to be measure 'm'.

Any idea what's going on?

Edit To answer @svick's questions, Vector3 is defined as:

type Vector3<[<Measure>]'u> =
    struct
        val x:float32<'u>
        val y:float32<'u>
        val z:float32<'u>
        new(x, y, z) = { x = x; y = y; z = z }
    end

And I'm also having some type inference problems defining it as a normal function:

let vector3 (v:DumpEngine.Vector3<_>) =
    Vector3(v.x / 1.f<_>, v.y / 1.f<_>, v.z / 1.f<_>)

Causes the function to be a Vector3<1> -> Microsoft.Xna.Framework.Vector3, which makes it quite unusable. I'm not sure this is a related issue, though.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

林空鹿饮溪 2024-12-24 11:47:52

另一种解决方案,通过使用强制转换而不是除法来完全规避该问题:

type Vector3<[<Measure>]'u> with
    member inline v.ToXna() =
        Microsoft.Xna.Framework.Vector3(float32 v.x, float32 v.y, float32 v.z)

Another solution, which circumvents the problem entirely by using a cast rather than a divison:

type Vector3<[<Measure>]'u> with
    member inline v.ToXna() =
        Microsoft.Xna.Framework.Vector3(float32 v.x, float32 v.y, float32 v.z)
蓝礼 2024-12-24 11:47:52

我不知道发生了什么,但这似乎有效:

let inline ToXna(v:Vector3<'a>) =
    Microsoft.Xna.Framework.Vector3(v.x / 1.f<_>, v.y / 1.f<_>, v.z / 1.f<_>)

不过,这是我能做到的最好的。

I have no idea what's going on, but this seems to work:

let inline ToXna(v:Vector3<'a>) =
    Microsoft.Xna.Framework.Vector3(v.x / 1.f<_>, v.y / 1.f<_>, v.z / 1.f<_>)

It's the best I managed to do, though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文