【问题标题】:Why can't you use generic type parameters in constraints on type extensions?为什么不能在类型扩展的约束中使用泛型类型参数?
【发布时间】:2013-10-22 11:46:10
【问题描述】:

我最近一直致力于为 TypeScript 0.9.1 定义生成 FFI 代码。我遇到了这个问题...

这段代码:

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

产生这种类型的错误:

类型参数'T'未定义。

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

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

我知道 [&lt;Extension&gt;] 属性,但我希望这些扩展可以从 F# 内部使用(用于 FunScript 项目)。

我可以将方法放在module 中。然而,这些方法将更难被发现。这不是我想要的。

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

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

我在想我可能必须解除类型限制。例如:ConcatWith&lt;'U when 'U :&gt; 'T IList&gt;(items : 'U) 将变为:ConcatWith(items : 'T IList)

【问题讨论】:

  • 我不确定我是否理解这个问题。看起来您错过了括号中的“T”。我的意思是,它应该是 ConcatWith
  • @Gustavo 否,类型参数应该来自类型声明 'T IListIList&lt;'T&gt;。就像我说的,它在大多数情况下都有效,只是不在类型扩展内的约束部分内。如果它是类型定义而不是类型扩展,它将起作用(即,不是type IList&lt;'T&gt; with,而是type IList&lt;'T&gt;() =)。

标签: generics f#


【解决方案1】:

这对我来说似乎是一个错误。

如果您实际需要表达的约束是此处示例中的约束 ('U :&gt; 'T IList),那么我认为您可以使用 #IList&lt;'T&gt; 类型解决它(但这不适用于更复杂的约束):

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

F# 3.1 支持使用 Extension 的 C# 样式扩展方法(定义和使用),因此这可能是另一种选择,但这意味着依赖于 F# 的新版本(但也许这还不错,如果有的话使用可在 F# 3.0 中工作的模块函数编写它的另一种方法)

【讨论】:

    猜你喜欢
    • 2012-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-23
    • 1970-01-01
    • 2020-09-10
    • 1970-01-01
    相关资源
    最近更新 更多