Я хочу предложить вам существующее решение для того, что вы хотите сделать.
Библиотека FSharpPlus предоставляет множество решений для последовательного решения этой проблемы.
Я думаю, что хорошей особенностью для этого типа векторов является Аппликативные математические операторы (см. Раздел «Использование аппликативных математических операторов»).
Вот пример с вашим кодом:
#r @"FSharpPlus.dll"
open FSharpPlus
open FSharpPlus.Data
open FSharpPlus.Math.Applicative
let v = ZipList [| 1; 2; 3 |]
let w = ZipList [| 4; 5; 6 |]
let sum = v .+. w
// val it : ZipList<int> = ZipList (seq [5; 7; 9])
let mul = v .*. w
// val it : ZipList<int> = ZipList (seq [4; 10; 18])
Вы также можете выполнять операции со скалярами:
v .* 6 ;;
// val it : ZipList<int> = ZipList (seq [6; 12; 18])
7 +. w ;;
val it : ZipList<int> = ZipList (seq [11; 12; 13])
Используемая здесь базовая абстракция: Applicative Functors , поскольку вектор (представьте ZipList как вектор) - это Applicative Functor, он просто работает.
ZipList, является немного стандартным в мире FP, но в качестве альтернативы вы также можете взглянуть на аппликатив ParallelArray . Если вам не нравятся имена, вы можете скопировать и вставить код и изменить определение на:
type TVector<'t> =
| Scalar of 't
| Vector of 't array
...
let v = Vector [| 1; 2; 3 |]
v .* 6 ;;
// or
v .*. Scalar 6
И, наконец, если вы не хотите использовать библиотеку, вы можете использовать ее как источник вдохновения и скопировать необходимый код. Это только там, и это работает.
Примечание
Что касается вашего исходного кода, если вы посмотрите на источники, на которые я указал, вы увидите, что он использует более функциональный подход и, например, он не ограничивает параметр типа на уровне типа, а ограничивает функции.
type Vector< ^F>(_values: ^F[]) =
let values: ^F [] = _values
member inline this.Values = values
member inline this.Dimension = Array.length values
// Constructs a Vector using given initializer
static member inline Init (n: int) (initializer: (int -> 'f)) =
Vector<'f>(Array.init n (fun i -> initializer (i + 1)))
member inline this.Item with get (i: int) = values.[i - 1]
// negate a vector
static member inline ( ~- ) (a: Vector<'f>) =
Vector<'f>.Init (Array.length a.Values) (fun i -> -a.[i])
Обратите внимание, что заглавная буква ˆF
используется только на уровне типа, тогда как в функциях (или статических членах) используется другой параметр типа, строчные буквы 'f
.