为什么F#中的权力运算符只适用于浮点数?
我从来没有见过一个语言指数或电力运营商只采取浮点数?
例如:
2 ** 2
引发错误The type 'int' does not support any operators named 'Pow'
这个devise决定是否有正当理由?
(**)
和pown
是两个不同的东西。 当你看到(**)
,你可以用对数来思考math公式。 当你看到pown
,这只是一系列的乘法。 我明白,起初可能会让人感到惊讶或困惑,因为大多数其他语言不会产生如此的差异(主要是因为整数通常被隐式转换为浮点值)。 即使在math中,也有一点区别:参见维基百科条目 ,第一个定义仅适用于正整数指数。
由于它们是两个不同的(但相关的)事物,它们具有不同的签名。 这里是(**)
:
^a -> ( ^b -> ^a) when ^a : (static member Pow : ^a * ^b -> ^a)
这里是:
^a -> (int -> ^a) when ^a : (static member get_One : -> ^a) and ^a : (static member ( * ) : ^a * ^a -> ^a) and ^a : (static member ( / ) : ^a * ^a -> ^a)
如果你创build了自己的types,你只需要让你的One
, (*)
和(/)
来使用pown
。 库会为你做循环(这是优化的,这不是天真的O(n))。
如果你想在你的types上使用(**)
运算符来得到非整数值,那么你必须编写完整的逻辑(并不像pown
algorithm)。
我认为把这两个概念分开是一个很好的devise决定。
对于整体权力,F#提供了另一个运营商: pown
。 另外,作为一个方面说明, (**)
和pown
都被重载,所以完全可以和其他提供相应成员的types一起使用(在(**)
; (*)
和(/)
运营商和一个静态One
属性的情况下)。
我不能说为什么F#团队select不在int
上模拟一个Pow
成员,但也许他们不觉得这是紧迫的,因为可以使用pown
运算符(而且,因为它可能更有意义的转换为float首先在大操作数的情况下)。
简短的答案是因为它不是整数types,甚至int64s非常有用。 2 ^ 26只给你〜1.84467441E19。 所以如果你有两个值X和Y都大于19,那么电源操作员将会导致溢出。
我同意它对于小值是有用的,但是它对于整数types通常不是有用的。
F#所基于的语言是OCaml,它不会执行运算符重载或自动数据强制(他们更喜欢显式强制)。
因此,即使添加双打也需要不同的运算符(+)。 我不确定这是否F#肯定会得到它的严格性,但我猜是这样。
在像Python或Scheme这样的dynamic语言中,如果数字太大,您会自动将数据强制转换为更大的数据存储。 例如,你可以有整数指数的整数给出一个大整数的结果。
OCaml和F#具有极端型安全的精神。