我该如何摆脱这种“无法概括"的问题?错误? [英] How can I get rid of this "Can not be generalised" error?
问题描述
我有此接口声明
type IModel<'value, 'search, 'target when 'target :> IModel<'value, 'search, 'target>> =
abstract token: string with get
abstract value: 'value with get
abstract search: 'search with get
abstract GetEmpty: unit -> 'target
abstract ReInitWith: #IModel<_, 'search, _> -> 'target
type IModelSimple<'value, 'search> =
inherit IModel<'value, 'search, IModelSimple<'value, 'search>>
abstract Update: ?token:string * ?value: 'value * ?search: 'search -> IModelSimple<'value, 'search>
以及创建对象表达式的此函数
and this function that creates a object expression
let rec mkModelSimple<'value, 'search> vctor sctor token value search =
{
new IModelSimple<'value, 'search> with
member this.token = token
member this.value = value
member this.search = search
member this.GetEmpty() = mkModelSimple vctor sctor token (vctor()) (sctor())
member this.ReInitWith (m: #IModel<_, 'search, _>) = mkModelSimple vctor sctor m.token this.value m.search
member this.Update(?t:Token, ?v: 'value, ?s: 'search) =
mkModelSimple vctor sctor (defaultArg t this.token) (defaultArg v this.value) (defaultArg s this.search)
}
这很好.
现在我想将上述类型重塑为
Now I want to remodel the above types into
type IModel<'value, 'target when 'target :> IModel<'value, 'target>> =
abstract token: string with get
abstract value: 'value with get
abstract GetEmpty: unit -> 'target
type ISearchModel<'value, 'search, 'target when 'target :> ISearchModel<'value, 'search, 'target>> =
inherit IModel<'value, 'target>
abstract search: 'search with get
abstract ReInitWith: ISearchModel<_, _, _> -> 'target
type ISearchModelSimple<'value, 'search> =
inherit ISearchModel<'value, 'search, ISearchModelSimple<'value, 'search>>
abstract Update: ?token:string * ?value: 'value * ?search: 'search -> ISearchModelSimple<'value, 'search>
与上面几乎相同,只是提取了搜索方面"
Almost the same as above only that the "search aspect" has been extracted
现在我在实现创建对象表达式的功能时
Now I when implementing the function to create the object expression
let rec mkSearchModelSimple<'value, 'search> vctor sctor token value search =
{
new ISearchModelSimple<'value, 'search> with
member this.token = token
member this.value = value
member this.search = search
member this.GetEmpty() = mkSearchModelSimple vctor sctor token (vctor()) (sctor())
member this.ReInitWith (m: #ISearchModel<_, 'search, _>) = mkSearchModelSimple vctor sctor m.token this.value m.search
member this.Update(?t:Token, ?v: 'value, ?s: 'search) =
mkSearchModelSimple vctor sctor (defaultArg t this.token) (defaultArg v this.value) (defaultArg s this.search)
}
我在方法ReInitWith
中得到了臭名昭著的This code is not sufficiently generic. The type variable 'a could not be generalized because it would escape its scope.
这让我发疯.对于一个我来说,我不理解为什么这种看似直接的变化根本造成了错误,而另一方面,试图传达的错误信息又是什么呢?
I get the infamous This code is not sufficiently generic. The type variable 'a could not be generalized because it would escape its scope.
on the method ReInitWith
This drives me crazy. For one I don't understand why this seemingly and otherwise straight forward change creates an error at all and on the other hand what is the error message trying to communicate?
推荐答案
第二个示例的一个问题是带有所有未绑定泛型类型参数的ISearchModel
方法:
One problem with your second example is this ISearchModel
method with all unbound generic type arguments:
abstract ReInitWith: ISearchModel<_, _, _> -> 'target
在您的第一个示例中,第二个泛型类型绑定到包含接口的'search
类型:
In your first example, the second generic type is bound to the containing interface's 'search
type:
abstract ReInitWith: #IModel<_, 'search, _> -> 'target
如果从第一个示例中删除该类型约束,它将无法以完全相同的方式进行编译.
If you remove that type constraint from your first example, it fails to compile in the exact same way.
如果您像在第一个示例中那样约束第二个通用类型,您的第二个示例将起作用:
Your second example works if you constrain the second generic type as you have in your first example:
type ISearchModel<'value, 'search, 'target when 'target :> ISearchModel<'value, 'search, 'target>> =
inherit IModel<'value, 'target>
abstract search: 'search with get
abstract ReInitWith: ISearchModel<_, 'search, _> -> 'target
这会为mkSearchModelSimple
产生以下类型签名:
This produces the following type signature for mkSearchModelSimple
:
val mkSearchModelSimple :
vctor:(unit -> 'value) ->
sctor:(unit -> 'search) ->
token:string ->
value:'value -> search:'search -> ISearchModelSimple<'value,'search>
注意:我用string
替换了您的Token
类型引用;没有提供其定义.
Note: I replaced your Token
type reference with string
; its definition wasn't provided.
这篇关于我该如何摆脱这种“无法概括"的问题?错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!