Я не эксперт в том, как работает алгоритм, поэтому может быть хорошая функциональная реализация, но стоит отметить, что использование локализованной мутации совершенно идиоматично в F #.
Ваша функция radix2
является функциональной снаружи - она принимает массив vector
в качестве входа, никогда не изменяет его, создает новый массив pvec
, который затем инициализирует (используя некоторую мутацию по пути)а затем возвращает его.Это аналогично тому, что используют встроенные функции, такие как Array.map
(который инициализирует новый массив, изменяет его, а затем возвращает).Часто это разумный способ сделать что-то, потому что некоторые алгоритмы лучше пишутся с использованием мутаций.
В этом случае вполне разумно также использовать локальные изменяемые переменные и циклы.Это сделает ваш код более читабельным по сравнению с хвостовой рекурсивной версией.Я не проверял это, но мой наивный перевод вашей функции outerLoop
состоял бы в том, чтобы использовать три вложенных цикла - что-то вроде этого:
let mutable size = 2
while size <= z do
let mid, step = size / 2, z / size
let mutable i = 0
while i < z do
for j in 0 .. mid - 1 do
let idx, k = i + j, step * j
let temp = pvec.[idx + mid] * unity.[k]
pvec.[idx + mid] <- (pvec.[idx] - temp)
pvec.[idx] <- (pvec.[idx] + temp)
i <- i + size
size <- size * 2
Это может быть не совсем верно (я сделал это просторефакторинг вашего кода), но я думаю, что это на самом деле более идиоматично, чем использование сложных вложенных хвостовых рекурсивных функций в этом случае.