F#有没有和C#一样的问题,你不能直接在泛型T类型中使用算术运算符?
你能写一个泛型的Sum函数来返回任何支持算术加法的值的和吗?
发布于 2010-02-09 10:19:35
正如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))
我们首先需要引用包含该功能的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>
。
发布于 2010-02-09 09:16:39
F#对此的支持有限。一个好的通用解决方案可能涉及类型类,一般不受CLR支持,尤其是F#。
F#使用“静态成员约束”和“内联”函数重载了算术运算符。这就是魔力,例如,+
操作符可以在int
和float
上工作。你可以编写inline
函数,其实现基于内置的数学操作符,并取得一些进展,但通常情况下,这不是微不足道的。你可以在CTP附带的F#源代码发行版中查看Array.sum
的源代码(在FSharp.Core中的array.fs中)来感受一下。
另请参阅此答案的“静态成员约束”和“模拟类型类”部分:
Functions with generic parameter types
以及库的不同部分,如
http://msdn.microsoft.com/en-us/library/ee370581(VS.100).aspx
http://msdn.microsoft.com/en-us/library/ee340262(VS.100).aspx
发布于 2010-02-09 09:34:53
你可以做这样的事情。
let inline sum<'a when 'a : (static member (+) : 'a -> 'a -> 'a)> a b =
a + b
let result = sum<int> 3 4
但是,如果我尝试使用let result = sum 3 4
,则会得到错误"type ambiguity inherent in the use of the operator '( + )'"
https://stackoverflow.com/questions/2225949
复制相似问题