Reputation: 16148
type Foo(size: int,data: 'T []) =
new(data: float []) =
Foo(sizeof<float>,data)
new(data: int []) =
Foo(sizeof<int>,data) //error: f# thinks that data is float []
member this.Size() = size
Basically I need several constructors with a generic array 'T [] and I only care for the size of 'T.
I want to use it like this:
Foo([|1,2,3,4|]).Size() // prints size of int
Foo([|1.f,2.f,3.f,4.f|]).Size() // prints size of float
How would I do this?
Update1:
I just realized that I can't let the compiler infer the size, I have to do this manually.
type Foo<'T>(size: int,data: 'T []) =
new(data: float []) =
Foo(4,data)
new(data: int []) =
Foo(16,data)
new(data: Vector3 []) =
Foo(Vector3.SizeInBytes,data)
member this.Size() = size
Would this be possible?
When I do
Foo([|new Vector3(1.f,1.f,1.f)|]
I want Foo to be of Foo<Vector3>
and therefore data should be of type data: Vector3 []
Upvotes: 2
Views: 277
Reputation: 148980
Try this:
type Foo<'T>(size: int, data: 'T []) =
new(data: 'T []) =
Foo(sizeof<'T>, data)
member this.Size() = size
Note that you should take care when testing this. When you call Foo([|1,2,3,4|])
, it infers that the the type T
is int * int * int * int
. Use semicolons to separate array elements:
Foo([|1;2;3;4|]).Size() // 4
Foo([|1.f;2.f;3.f;4.f|]).Size() // 4
Foo([|1.m;2.m;3.m;4.m|]).Size() // 16
Update
Given your updated question, it appears you're trying to do a bit of partial specialization. I'd recommend not trying to do this within the generic class itself, after all, the whole point of generics in .NET is that you should not have to have different strategies for each type you want to use. Instead, create a separate type with static factories for generating your Foo
objects with multiple overloads for the various types you'd like to create:
type Foo<'T>(size: int, data: 'T []) =
member this.Size() = size
type Foo =
static member from (data : int[]) = Foo(16, data)
static member from (data : float[]) = Foo(4, data)
static member from (data : Vector3[]) = Foo(Vector3.SizeInBytes, data)
static member from (data : 'T[]) = Foo(sizeof<'T>, data)
Foo.from([|1;2;3;4|]).Size() // 16
Foo.from([|1.f;2.f;3.f;4.f|]).Size() // 4
Foo.from([|Vector3(1.f,1.f,1.f)|]).Size() // Vector3.SizeInBytes
Foo.from([|1.m;2.m;3.m;4.m|]).Size() // 16
Upvotes: 2