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

时间:2013-10-22 11:46:10

标签: generics f#

我最近一直致力于为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)

1 个答案:

答案 0 :(得分:2)

对我来说这看起来像个错误。

如果您实际需要表达的约束是此处示例中的约束('U :> 'T IList),那么我认为您可以使用#IList<'T>类型来解决它(但这对于更复杂的情况不起作用约束):

type 'T IList with
    member __.ConcatWith(items : #IList<'T>) : 'T[] = failwith "not implemented"
使用Extension的C#样式扩展方法在F#3.1中得到支持(定义和消费),这可能是另一种选择,但这意味着依赖于新版本的F#(但也许这不是那么糟糕,如果有一种替代方法可以使用模块函数编写它,可以在F#3.0中使用