2015-12-22 17 views
6

以下の収率推論された型制約

この構築物は、型注釈で示されるよりも、一般的なように、コードの原因を理解しようとしています。型変数 '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 

ここでは、何が起こっていますか?最初の例では、メソッドがプライベート値の割り当てでは認識されるが、合法的な汎用メソッドとして認識されないのはなぜですか?

+4

コンパイラのようにここに一般化する必要がありますが、何らかの理由でではありません –

+0

@JohnPalmerの楽しい事: ''を削除するとすぐになります - これは仕様やバグのどこかに隠されている境界ケースの1つです – Carsten

+0

値を変更可能にする場合、 'let myableValue:bool = false'を置き、メソッドの後に' member this.myValue = this.Value "SomeBooleanProperty"を置きます。これを前に置くとエラーになります。仕様にジェネリックスの言及がないので、コーナーケースのバグであるようです。 – jpe

答えて

2

警告(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の質問の下にある他のコメントには、より興味深い手がかりが含まれています。これは は、x = this.Value () メンバーthis.Value <'P>()=()しましょう;; `それはそうです=と)`>タイプテスト(:私はこれはバグかもしれない考えています - REPROシンプル