Why does F# constrain my code and remove generics?
f#
Solution
The F# compiler seems to specialise generic types if they are used at a particular instantiation in the same block of code. Try splitting up your declaration like this:
type VBO<'T when 'T : (new : unit -> 'T) and 'T : struct and 'T :> ValueType> =
{ Handle : int
target : BufferTarget
size : int
dataSize : int
data : 'T []
pos : int
usage : BufferUsageHint }
type VBO =
static member CreateImpl(target, size, pos, usage, dataSize, (data : 'T [])) =
let h = GL.GenBuffer()
{ Handle = h
target = target
size = size
dataSize = dataSize
data = data
pos = pos
usage = usage }
type VBO with
static member Create(target, size, pos, usage, (data : Vector3 [])) =
VBO.CreateImpl(target, size, pos, usage, Vector2.SizeInBytes, data)
static member Create(target, size, pos, usage, (data : Vector2 [])) =
VBO.CreateImpl(target, size, pos, usage, Vector2.SizeInBytes, data)
Problem
``` type VBO<'T when 'T : (new : unit -> 'T) and 'T : struct and 'T :> ValueType> = { Handle : int target : BufferTarget size : int dataSize : int data : 'T [] pos : int usage : BufferUsageHint } type VBO = static member Create(target, size, pos, usage, (data : Vector3 [])) = VBO.CreateImpl(target, size, pos, usage, Vector2.SizeInBytes, data) // Type mismatch. Expecting Vector3 but found Vector2 static member Create(target, size, pos, usage, (data : Vector2 [])) = VBO.CreateImpl(target, size, pos, usage, Vector2.SizeInBytes, data) // This construct causes code to be less generic than indicated by the type annotations. // The type variable 'T has been constrained to be type 'Vector3'. static member CreateImpl(target, size, pos, usage, dataSize, (data : 'T [])) = let h = GL.GenBuffer() { Handle = h target = target size = size dataSize = dataSize data = data pos = pos usage = usage } ``` F# tries to constrain my code but I want it to be generic. I don't really care about what type the data is I just need it pass in the correct dataSize. What have I done wrong?