Как уже упоминалось Брайен, есть некоторые встроенные в поддержку общего arithmethic, и вы можете использовать «статические ограничения», которые позволяют определить некоторые общие выполняет функции (хотя это немного ограничено).
В дополнение к этому вы также можете использовать динамические «числовые ассоциации», которые при использовании в функции немного медленнее, но их можно использовать, например, для определения собственного вектора или типа матрицы. Вот пример:
#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>
.
Я думал, что вам нужно использовать '^ a' вместо' 'a' при использовании статических ограничений в F #, но я могу ошибаться ... –
Оба работают в этом случае. – gradbot
В этом конкретном случае вам даже не нужно указывать общие параметры или ограничения, потому что они могут быть выведены: 'let inline sum a b = a + b' – kvb