(**)
и pown
- это две разные вещи. Когда вы видите (**)
, вы можете думать о математической формуле, используя логарифмы. Когда вы видите pown
, это просто серия умножений. Я понимаю, что поначалу это может удивлять / сбивать с толку, потому что большинство других языков не имеют такой разницы (в основном потому, что целые числа часто неявно преобразуются в значения с плавающей запятой). Даже в математике есть небольшая разница: см. Запись Википедии , первое определение работает только для положительных целочисленных показателей.
Поскольку это две разные (но связанные) вещи, они имеют разные подписи. Вот (**)
:
^a -> ( ^b -> ^a) when ^a : (static member Pow : ^a * ^b -> ^a)
А вот и pown
:
^a -> (int -> ^a)
when ^a : (static member get_One : -> ^a) and
^a : (static member ( * ) : ^a * ^a -> ^a) and
^a : (static member ( / ) : ^a * ^a -> ^a)
Если вы создаете свой собственный тип, вам нужны только ваши One
, (*)
и (/)
, чтобы он работал с pown
. Библиотека сделает цикл за вас (она оптимизирована, это не наивный O (n)).
Если вы хотите использовать оператор (**)
в вашем типе для нецелых значений, вам придется написать полную логику (и это не будет тот же алгоритм, что и в pown
).
Я думаю, это было хорошее дизайнерское решение, чтобы разделить две концепции.