该参数的使用方式将其限制为始终为DerrivedType(The parameter has been used in a way that constrains it to always be De

编程入门 行业动态 更新时间:2024-10-27 00:29:25
该参数的使用方式将其限制为始终为DerrivedType(The parameter has been used in a way that constrains it to always be DerrivedType)

嗨,我刚刚开始使用F#进行编程,并且遇到类型问题。 我有这个功能:

member private this.UpdateStats<'T when 'T :> StatisticsBase>(passed: bool, stats: 'T) = //more stuff.. stats

我这样称呼它:

this.UpdateStats<GroupStats>(true, GroupStats(Id = Guid.NewGuid()))

编译器说:

该参数的使用方式将其限制为始终为GroupStats。

GroupStats继承自StatisticsBase。 我该怎么做才能使该函数可用于从StatisticsBase继承的所有实体?

类型:

[<AllowNullLiteral>] type StatisticsBase() = member val Id = String.Empty with get,set [<AllowNullLiteral>] type GroupStats() = inherit Stats()

StatisticsBase实际上继承自C#类型并在存储库中使用,但我可以使用上面的代码重现错误

Hi I just started programming in F# and am stuck on a type issue. I have this function:

member private this.UpdateStats<'T when 'T :> StatisticsBase>(passed: bool, stats: 'T) = //more stuff.. stats

I'm calling it like this:

this.UpdateStats<GroupStats>(true, GroupStats(Id = Guid.NewGuid()))

The compiler says:

The parameter has been used in a way that constrains it to always be GroupStats.

GroupStats inherit from StatisticsBase. What do I have to do to make the function usable for all entities that inherit from StatisticsBase?

types:

[<AllowNullLiteral>] type StatisticsBase() = member val Id = String.Empty with get,set [<AllowNullLiteral>] type GroupStats() = inherit Stats()

StatisticsBase actually inherits from a C# type and is used in a repository, but I can reproduce the error with the code above

最满意答案

经过多次来回,我们已经能够确定您的实际非工作代码是这样的(未来提示:提供更多信息):

type SomeType() = member this.M2() = this.M<GroupStats>(true, GroupStats()) member private this.M<'T when 'T :> Stats>(x: bool, t: 'T) = t

该代码确实会产生所描述的错误。 这是因为F#类型推断从上到下,从左到右。 但是有一个例外:类(和其他相互重新定义的组)获得两次类型推断 - 第一个签名,然后是主体。

当编译器首次遇到M2的主体时,它确定方法M必须返回GroupStats 。 之后,当编译器遇到M的主体时,它看到M的返回值与参数t相同,这意味着M必须返回'T 但是由于编译器已经知道,通过检查M2的主体, M必须返回GroupStats ,因此'T必须是GroupStats 。

如果在M2之前定义M则不会发生这种情况:在这种情况下,类型推断将首先遇到M的主体并正确地确定其返回类型为'T ,然后它将与M2的主体匹配,并且意志没问题。

从上面可以得出两种解决方案:首先,你可以在M2之前定义M 其次,您可以只显式指定M的返回类型:

member private this.M<'T when 'T :> Stats>(x: bool, t: 'T): 'T = t

这样,它的返回类型将在第一次传递后变为已知,并且问题消失。

After much back and forth, we have been able to ascertain that your actual non-working code is like this (tip for the future: provide more information):

type SomeType() = member this.M2() = this.M<GroupStats>(true, GroupStats()) member private this.M<'T when 'T :> Stats>(x: bool, t: 'T) = t

This code will indeed produce the described error. This is because F# type inference works top-to-bottom, left-to-right. But there is an exception: classes (and other mutually recusrive definition groups) get two passes of type inference - first signatures, then bodies.

When the compiler first comes across the body of M2, it determines that method M must return GroupStats. Later, when the compiler comes across the body of M, it sees that M's return value is the same as parameter t, which means that M must return 'T. But since the compiler already knows, from examining the body of M2, that M must return GroupStats, it follows that 'T must be GroupStats.

This doesn't happen if M is defined before M2: in this case, type inference will first encounter the body of M and correctly determine its return type to be 'T, which will then match up with the body of M2, and the will be no problem.

From the above, two solutions can be formulated: first, you could define M before M2. Second, you could just explicitly specify the return type of M:

member private this.M<'T when 'T :> Stats>(x: bool, t: 'T): 'T = t

This way, its return type will become known after the first pass, and the problem disappears.

更多推荐

本文发布于:2023-08-04 22:36:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1424468.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:将其   参数   方式   constrains   DerrivedType

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!