正如brian所提到的,有一些对泛型算术的内置支持,你可以使用'静态约束',它允许你自己定义一些泛型函数(尽管这有点受限).
除此之外,您还可以使用动态"数字关联",这在函数中使用时速度稍慢,但它可以很好地用于定义您自己的向量或矩阵类型.这是一个例子:
#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))
Run Code Online (Sandbox Code Playgroud)
我们首先需要引用包含该功能的F#PowerPack库.然后我们定义一个带签名的泛型函数'a -> 'a -> 'a
.第一行动态地获取数字操作以使用该类型'a
(它实际上使用一些查找表,类型为键).然后,您可以使用数字操作对象的方法来执行乘法,加法(Multiply
,Add
)等许多其他操作.该功能适用于任何数字:
twoTimesLarger 3 4
twoTimesLarger 2.3 2.4
twoTimesLarger "a" "b" // Throws an exception!
Run Code Online (Sandbox Code Playgroud)
定义自己的数字类型时,可以定义其数值运算并使用它们进行注册GlobalAssociations.RegisterNumericAssociation
.我相信这也意味着你可以使用内置的F#Matrix<YourType>
并Vector<YourType>
在注册操作之后.
F# 对此提供一些有限的支持。一个好的通用解决方案可能涉及类型类,但 CLR 通常不支持类型类,尤其是 F# 不支持类型类。
F# 使用“静态成员约束”和“内联”函数重载了算术运算符。这就是使操作员能够在s 和s+
上工作的魔力。您可以编写其实现基于内置数学运算符的函数并取得一些进展,但一般来说这并不简单。您可以查看CTP 附带的 F# 源代码发行版中的源代码(在 FSharp.Core 中的 array.fs 中)来感受一下。int
float
inline
Array.sum
另请参阅此答案的“静态成员约束”和“模拟类型类”部分:
以及图书馆的各个部分,例如
http://msdn.microsoft.com/en-us/library/ee370581(VS.100).aspx
http://msdn.microsoft.com/en-us/library/ee340262(VS.100).aspx