Jusqu'à présent, j'ai été assez impressionné par l'inférence de type dans F#, cependant j'ai trouvé quelque chose qu'il n'a pas vraiment compris :
//First up a simple Vect3 type
type Vect3 = { x:float; y:float; z:float } with
static member (/) (v1 : Vect3, s : float) = //divide by scalar, note that float
{x=v1.x / s; y= v1.y /s; z = v1.z /s}
static member (-) (v1 : Vect3, v2 : Vect3) = //subtract two Vect3s
{x=v1.x - v2.x; y= v1.y - v2.y; z=v1.z - v2.z}
//... other operators...
//this works fine
let floatDiff h (f: float -> float) x = //returns float
((f (x + h)) - (f (x - h)))/(h * 2.0)
//as does this
let vectDiff h (f: float -> Vect3) x = //returns Vect3
((f (x + h)) - (f (x - h)))/(h * 2.0)
//I'm writing the same code twice so I try and make a generic function:
let genericDiff h (f: float -> 'a) x : 'a = //'a is constrained to a float
((f (x + h)) - (f (x - h)))/(h * 2.0)
Lorsque j'essaye de construire cette dernière fonction, un gribouillis bleu apparaît sous le signe de la division et le compilateur affiche le redoutable avertissement suivant : "This construct causes code to be less generic than indicated by the type annotations" (Cette construction rend le code moins générique qu'indiqué par les annotations de type). La variable de type 'a a été contrainte à être de type 'float'". Je fournis au Vect3 le code approprié /
pour la fonction. Pourquoi m'avertit-il ?