Как упомянул Брайан, есть некоторая встроенная поддержка универсальной арифметики, и вы можете использовать «статические ограничения», которые позволяют вам самостоятельно определять некоторые универсальные функции (хотя это немного ограничено).
В дополнение к этому вы также можете использовать динамические «числовые ассоциации», которые немного медленнее при использовании в функции, но их можно использовать, например, для определения собственного вектора или типа матрицы. Вот пример:
#r "FSharp.PowerPack.dll"
open Microsoft.FSharp.Math
let twoTimesLarger (n:'a) (m:'a) =
let ops = GlobalAssociations.GetNumericAssociation<'a>()
let sel = if ops.Compare(n, m) > 0 then n else m
ops.Multiply(sel, ops.Add(ops.One, ops.One))
Сначала нам нужно обратиться к библиотеке F # PowerPack, которая содержит эту функциональность. Затем мы определяем обобщенную функцию с сигнатурой 'a -> 'a -> 'a
. Первая строка динамически получает числовые операции для работы с типом 'a
(по сути, она использует некоторую таблицу поиска с типом в качестве ключа). Затем вы можете использовать методы объекта числовых операций для выполнения таких операций, как умножение, сложение (Multiply
, Add
) и многие другие. Функция работает с любыми номерами:
twoTimesLarger 3 4
twoTimesLarger 2.3 2.4
twoTimesLarger "a" "b" // Throws an exception!
Когда вы определяете свой собственный числовой тип, вы можете определить его числовые операции и зарегистрировать их, используя GlobalAssociations.RegisterNumericAssociation
. Полагаю, это также означает, что вы сможете использовать встроенные F # Matrix<YourType>
и Vector<YourType>
после регистрации операций.