2016-06-18 8 views
9

ich einen allgemeineren Fall für den (!) Operator zu definieren versuche, wie folgt,F # Aufruf Inline-Funktion mit Variablen vom Typ

let inline (!) (cell : ^a) = 
    (^a : (member Value : ^b) cell) 

also, dass sie nicht nur für ref Typen funktionieren, aber jede Art mit einem Value Mitglied.

> !(ref 10) ;; 
val it : int = 10 

> !(lazy 5) ;; 
val it : int = 5 

Aber Problem entsteht, wenn ich versuche, es zu einer Variablen vom Typ mit Typ,

> let getValue (c : 'a ref) = !c ;; 

    let getValue (c : 'a ref) = !c ;; 
    ------------------^^ 

C:\Users\User\AppData\Local\Temp\stdin(6,19): warning FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type 'obj'. 

val getValue : c:obj ref -> obj 

aufzubringen, während es funktioniert gut, wenn ich die Inline-Funktion erweitern.

> let getValue (c : 'a ref) = c.Value ;; 

val getValue : c:'a ref -> 'a 

Weiß jemand, warum das passiert? Vielen Dank.

Antwort

5

Da Ihre getValue-Funktion nicht inline ist, funktionieren die Einschränkungen nicht.

Das Problem ist, dass das .NET-Typsystem den Typ der Einschränkungen nicht speichern kann, die F # in inline verwenden kann.

Wenn Sie eine Nicht-Inline-Funktion verwenden, die eine Inline-Funktion auf diese Weise verwendet, erhalten Sie daher einen Fehler.

+0

Die letzte Version von 'getValue' ist nur eine manuelle Erweiterung der früheren Version, ich weiß, dass ich hier etwas verpasst habe, aber ich kann immer noch nicht sehen, wie erstere mehr Typabhängigkeiten einführt, als .NET nicht erfassen. – Doaz

+0

Ich denke, dass die Einschränkungen von 'getValue' eine Obermenge der Einschränkungen von'! 'Sind. Da die Einschränkungen für 'getValue' inline erforderlich sind, kann es keine Nicht-Inline-Funktion sein –