为什么不能在类型扩展的约束中使用通用类型参数?

3
我是一名有用的助手,可以为您翻译文本。
最近我一直在为TypeScript 0.9.1定义生成FFI代码。 我遇到了这个问题...
这段代码:
    type 'T IList with
        member __.ConcatWith<'U when 'U :> 'T IList>(items : 'U) : 'T[] = failwith "not implemented"

产生了这种类型错误:

类型参数'T'未定义。

注意:此错误仅在类型约束部分内发生。在其他地方使用泛型类型参数(例如,作为返回类型)是正常的。

但是,如果我定义一个类型而不是扩展类型,那就没问题了。不幸的是,我没有这个奢侈品。我定义的扩展有时需要位于单独的程序集中。

我知道[<Extension>]属性,但我希望可以从F#内部消耗扩展(对于FunScript项目)。

我可以把方法放在一个module中。但是,这样方法会更难被发现。这不是我想要的。

我可以使用C#。但是,那时我将无法添加扩展索引和属性。因此,这是不可接受的。

是否有任何解决此问题的方法?

我正在考虑必须去掉类型约束。例如:ConcatWith<'U when 'U :> 'T IList>(items : 'U) 将变成: ConcatWith(items : 'T IList)


我不确定我理解这个问题。看起来你在括号里漏掉了'T。我的意思是,当'U...时,它应该是ConcatWith<'T,'U>。 - Gus
1
@Gustavo 不,类型参数应该来自类型声明 'T IListIList<'T>。就像我说的,在大多数情况下它都有效,只是在类型扩展的约束部分内部无效。如果它是类型定义而不是类型扩展,它将起作用(即不是 type IList<'T> with 而是 type IList<'T>() =)。 - ZachBray
1个回答

2

我认为这看起来像是一个bug。

如果你实际需要表达的约束条件是这个示例中的约束条件 ('U :> 'T IList),那么我认为你可以使用#IList<'T>类型来解决它(但对于更复杂的约束条件可能无效):

type 'T IList with
    member __.ConcatWith(items : #IList<'T>) : 'T[] = failwith "not implemented"

在F# 3.1中,支持使用Extension定义和使用C#风格的扩展方法,这可能是另一种选择,但这意味着要依赖于新版本的F#(但如果有其他方法可以在F# 3.0中使用模块函数来编写它,那么也许这并不是很糟糕)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接