2015-12-22 41 views
6

le seguenti reseCercando di capire vincoli tipo derivato

Questo costrutto causa il codice di essere meno generico di quelli indicati dalle annotazioni di tipo. La variabile di tipo 'P è stata vincolata per essere di tipo' bool '.

per il lato destro del let myValue = espressione, e

Questo codice è meno generico di quanto richiesto dalle sue annotazioni perché il tipo esplicito variabile 'P' non può essere generalizzata. Era costretto a essere "bool".

per il generico <'P> nel metodo Value:

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` 

Tuttavia, questo compila proprio bene e non produce avvisi o errori:

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 

cosa sta succedendo, qui? Perché, nel primo esempio, il metodo è riconosciuto nell'assegnazione del valore privato, ma non come un metodo legittimamente generico?

+4

più semplice Repro - penso che questo potrebbe essere un bug: '> tipo di test() come questo = let x = This.Value () membro This.Value <'P>() =() ;;' Sembra come il compilatore dovrebbe essere generalizzato qui, ma non è per qualche motivo –

+0

@JohnPalmer cosa divertente: non appena si rimuoverà il '' - Sono d'accordo che si tratta di alcuni casi limite nascosti da qualche parte nelle specifiche o di un bug – Carsten

+0

Se rendi il valore mutabile: 'lascia mutable myValue: bool = false' e ​​inserisci' member this.myValue = this.Value "SomeBooleanProperty" 'dopo Method, quindi funziona. Se lo metti prima, dà l'errore. Sembra essere un bug del caso angolo, in quanto non ci sono menzioni di generici nelle specifiche. – jpe

risposta

2

L'avvertimento (FS0064) è sollevata da una chiamata alla funzione CheckWarnIfRigid all'interno SolveTyparEqualsTyp divertente da ConstraintSolver.fs. Dopo che l'avviso è stato sollevato, SolveTyparEqualsTyp continuerà (poiché non vi sono errori fino ad ora) per risolvere i vincoli di tipo. Il commento di 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 

Questo porta ad errori FS0663 per membro Value definizione l'esempio di OP. Seguito dall'errore FS0660. Per qualche motivo ignoro, si verifica qualche propagazione.

Forse l'inferenza di tipo è troppo aggressiva. @jpe e altri commenti sotto la domanda dell'OP contengono altri indizi interessanti.