2014-01-07 41 views
2
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 

基本上我需要几个带有泛型数组'T []的构造函数,我只关心'T'的大小。F#中的通用构造函数#

我想用这样的:

Foo([|1,2,3,4|]).Size() // prints size of int 
Foo([|1.f,2.f,3.f,4.f|]).Size() // prints size of float 

我将如何做到这一点?

UPDATE1:

我才意识到,我不能让编译器推断大小,我必须手动完成。

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 

会这样吗?

当我做 Foo([|new Vector3(1.f,1.f,1.f)|]我想美孚是的Foo<Vector3>,因此数据应该是数据类型:的Vector3 []

回答

2

试试这个:

type Foo<'T>(size: int, data: 'T []) = 
    new(data: 'T []) = 
     Foo(sizeof<'T>, data) 
    member this.Size() = size 

请注意,您应该注意,当测试这个。当您致电Foo([|1,2,3,4|])时,它推断T类型为int * int * int * int。用分号来分隔数组元素:

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 

更新
鉴于你的更新问题,看来你试图做一些局部的专业化。我建议而不是试图在泛型类本身内部做到这一点,毕竟,.NET中泛型的全部要点是,您不应该为每种类型使用不同的策略。取而代之的是,创建一个单独的类型与产生的Foo对象有多个重载,各种类型的静态工厂你想创建:

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