2014-01-07 5 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, чтобы быть 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 

Update
Учитывая Ваш обновленный вопрос, кажется, что вы пытаетесь сделать немного частичной специализации. Я бы порекомендовал не, пытаясь сделать это внутри самого универсального класса, в конце концов, вся точка родословной в .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 
Смежные вопросы