正如我上面评论的那样,这不是一种特别好的排序方式(假设我理解 Scala 代码,我可能不理解)。这是它似乎在做什么的 OCaml 翻译:
let insertion_sort l =
let add1 sortedl x =
let le, gt = List.partition ((>=) x) sortedl
in
le @ [x] @ gt
in
List.fold_left add1 [] l
在您编写 FP 代码一段时间后,折叠变得很自然。其目的是以已知顺序(例如,最左边的优先)处理来自数据结构(例如,列表)的一系列元素,同时保持一些在您进行处理时传递的状态。在最简单的情况下(如这里),状态也是您的最终答案。在其他情况下,您需要携带一些额外的状态以及最终答案。在这些情况下,您会在最后提取最终答案。
也许我不应该这么说,但是 fold 就像for(;;)
C 家族中的语句一样,只是它封装了您计划在循环中修改的所有状态。通过这种方式,它是一种很好控制的迭代形式。
对应看起来像这样:
for(state = S, x = first(D); more(D); x = next(D)) { state = E(state, x) }
fold_left (fun state x -> E state x) S D
在你习惯了封装修改后的状态之后,它通常会变得非常有用。很多时候,你折叠的函数(如上面的 add1 )在许多其他情况下也很有用,因为折叠的结构需要在那个地方有一个普遍有用的函数。
请注意,特别是 fold 函数包含有关如何遍历数据结构的所有知识。folded 函数只需要知道如何处理每个元素。因此,您可以在不更改任何其他代码的情况下自由更改数据结构(和折叠)。您还可以使用add1
具有不同数据结构的相同折叠函数(如上)。