我该如何摆脱这种“无法概括"的问题?错误? [英] How can I get rid of this "Can not be generalised" error?

查看:69
本文介绍了我该如何摆脱这种“无法概括"的问题?错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有此接口声明

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆