【问题标题】:Trying to understand inferred type constraints试图理解推断的类型约束
【发布时间】:2015-12-22 05:02:17
【问题描述】:

以下产生

这种构造导致代码比类型注释所指示的更通用。类型变量 'P 已被限制为类型 'bool'。

let myValue = 表达式的右侧,以及

此代码的通用性低于其注释所需的通用性,因为显式类型变量“P”无法通用化。它被限制为“布尔”。

对于Value 方法中的通用<'P>

type MyTypeA<'T> (myObject : 'T) as this =
    let myValue = this.Value<bool> "SomeBooleanProperty"

    member this.Value<'P> name = typeof<'T>.GetProperty(name, typeof<'P>).GetValue(myObject, null) :?> 'P`

但是,这编译得很好,不会产生警告或错误:

type MyTypeB<'T> (myObject : 'T) as this =
    member this.Value<'P> name = typeof<'T>.GetProperty(name, typeof<'P>).GetValue(myObject, null) :?> 'P

    member this.Method<'P> name = this.Value<'P> name

这是怎么回事?为什么在第一个示例中,该方法在私有值的分配中被识别,而不是合法的泛型方法?

【问题讨论】:

  • 更简单的重现 - 我认为这可能是一个错误:&gt; type test() as this = let x = this.Value&lt;bool&gt;() member this.Value&lt;'P&gt;() = ();; 似乎编译器应该在这里泛化,但由于某种原因不是
  • @JohnPalmer 有趣的事情:只要您删除 &lt;bool&gt;,它就会立即生效 - 我同意这是隐藏在规范中某处的一些边界案例或错误
  • 如果你让 Value 可变:let mutable myValue : bool = false 并在 Method 之后放置 member this.myValue = this.Value&lt;bool&gt; "SomeBooleanProperty",那么它就可以工作。如果你把它放在前面,它会给出错误。这似乎是一个极端情况下的错误,因为规范中没有提到泛型。
  • 澄清一下:type MyTypeA&lt;'T&gt; (myObject : 'T) as this = let mutable myValue : bool = false do myValue &lt;- this.myVal2 member this.Value&lt;'P&gt; name = typeof&lt;'T&gt;.GetProperty(name, typeof&lt;'P&gt;).GetValue(myObject, null) :?&gt; 'P member this.myVal2 = this.Value&lt;bool&gt; "SomeBooleanProperty" 有效,但 type MyTypeA&lt;'T&gt; (myObject : 'T) as this = let mutable myValue : bool = false do myValue &lt;- this.myVal2 member this.myVal2 = this.Value&lt;bool&gt; "SomeBooleanProperty" member this.Value&lt;'P&gt; name = typeof&lt;'T&gt;.GetProperty(name, typeof&lt;'P&gt;).GetValue(myObject, null) :?&gt; 'P 无效。

标签: f# type-inference type-constraints


【解决方案1】:

警告 (FS0064) 是由 ConstraintSolver.fs 中的 SolveTyparEqualsTyp 函数调用 CheckWarnIfRigid 函数引发的。 发出警告后,SolveTyparEqualsTyp 将继续(因为到目前为止没有错误)解决类型约束。 SolveTyparEqualsTyp 的注释是:

/// Add the constraint "ty1 = ty" to the constraint problem, where ty1 is a type variable. 
/// Propagate all effects of adding this constraint, e.g. to solve other variables 

这会导致 OP 示例中成员 Value 定义的错误 FS0663。随后出现错误 FS0660。 出于某种我忽略的原因,发生了一些传播。

也许类型推断过于激进。 @jpe 和 OP 问题下方的其他 cmets 包含更多有趣的线索。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-23
    • 2020-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-28
    • 1970-01-01
    相关资源
    最近更新 更多