F# 从这个数组中选择子集最“实用”的方法是什么?
我想更熟悉函数式编程,我自己设置的第一个教育任务是将一个计算音频的程序从C转换为F。原始应用程序的核心是一个大for循环,它在一个大数组中选择值的子集;采用哪些值取决于最后接受的值以及自那时以来看到的值的排序列表。有几个变量在迭代之间保持不变,以跟踪确定下一个值的进度 我第一次尝试使这个循环更具功能性,涉及一个尾部递归函数,其参数包括数组、迄今为止的结果集、最近看到的值的排序列表,以及在执行之间需要保留的其他一些项。这看起来很笨重,而且我觉得把以前作为变量的所有东西都转换成这个递归函数的参数并没有什么好处 一个函数式编程大师如何处理这类任务?这是一种例外情况吗?在这种情况下,纯函数方法不太合适,而我之所以回避可变变量,仅仅是因为我觉得它们降低了我函数的纯度,这是错误的吗?也许它们不会降低它的纯度,因为它们只存在于该函数的作用域内。我还没有这种感觉 下面是对代码的尝试提炼,使用一些let语句,state removed temp的实际组件是需要处理的中间结果数组:F# 从这个数组中选择子集最“实用”的方法是什么?,f#,functional-programming,c#-to-f#,F#,Functional Programming,C# To F#,我想更熟悉函数式编程,我自己设置的第一个教育任务是将一个计算音频的程序从C转换为F。原始应用程序的核心是一个大for循环,它在一个大数组中选择值的子集;采用哪些值取决于最后接受的值以及自那时以来看到的值的排序列表。有几个变量在迭代之间保持不变,以跟踪确定下一个值的进度 我第一次尝试使这个循环更具功能性,涉及一个尾部递归函数,其参数包括数组、迄今为止的结果集、最近看到的值的排序列表,以及在执行之间需要保留的其他一些项。这看起来很笨重,而且我觉得把以前作为变量的所有东西都转换成这个递归函数的参数并没
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
像这样的东西用折叠
let filter list =
List.fold (fun statevar element -> if condition statevar then statevar else element) initialvalue list
尝试使用Seq.skip和Seq.take:
let subset (min, max) seq =
seq
|> Seq.skip (min)
|> Seq.take (max - min)
此函数将接受数组但返回序列,因此可以使用Array.ofSeq将其转换回
PS:如果你的目标是保持你的程序正常运行,最重要的规则是:尽可能避免可变性。这意味着您可能不应该使用数组;使用不可变的列表。如果你使用的是快速随机存取的数组,那就试试吧;请确保永远不要设置索引。这个问题不是从数组中获取块