Я хотел бы получить более удобное функциональное программирование, и первая образовательная задача, которую я установил, - это преобразование программы, которая вычисляет звуковые частоты от C# до F #. Мяг оригинального приложения представляет собой большой цикл «для», который выбирает подмножество значений в большом массиве; какие значения взяты, зависит от последнего принятого значения и ранжированного списка значений, наблюдаемых с тех пор. Существует несколько переменных, которые сохраняются между итерациями для отслеживания прогресса в направлении определения следующего значения.Какой самый «функциональный» способ выбрать подмножество из этого массива?
Моя первая попытка сделать этот цикл более «функциональным» связана с хвостовой рекурсивной функцией, аргументы которой включают в себя массив, набор результатов до сих пор, ранжированный список недавно полученных значений и несколько других элементов, которые необходимо сохранить между казнями. Это кажется неуклюжим, и я не чувствую, что получил что-либо, превратив все, что раньше было переменной в параметр этой рекурсивной функции.
Каким образом мастер функционального программирования подходит к этой задаче? Является ли это исключительной ситуацией, когда «чистый» функциональный подход не совсем подходит, и я ошибаюсь в том, чтобы избегать изменчивых переменных только потому, что я чувствую, что они уменьшают «чистоту» моей функции? Возможно, они не делают его менее чистым, так как они существуют только внутри области этой функции. Я еще не чувствую этого.
Вот попытка перегонка кода, с некоторыми «пусть» заявления и действительные компоненты состояния удалены («Темп» промежуточный результат массив, который должен быть обработан):
let fif (_,_,_,_,fif) = fif
temp
|> Array.fold (fun (a, b, c, tentativeNextVals, acc) curVal ->
if (hasProperty curVal c) then
// do not consider current value
(a, b, c, Seq.empty, acc)
else
if (hasOtherProperty curVal b) then
// add current value to tentative list
(a, b, c, tentativeNextVals.Concat [curVal], acc)
else
// accept a new value
let newAcceptedVal = chooseNextVal (tentativeNextVals.Concat [curVal])
(newC, newB, newC, Seq.empty, acc.Concat [newAcceptedVal])
) (0,0,0,Seq.empty,Seq.empty)
|> fif
Этот вопрос не о взятии блока из массива –