So far I've been quite impressed with the type inference in F#, however I have found something that it didn't really get:
//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)
When I try and build this last function a blue squiggly appears under the divide sign and the complier says the dreaded warning of "This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type 'float'". I provide the Vect3 with the suitable /
operator for the function. Why is it warning me?