任何人都可以用一种非常简单的方式来解释什么是F#中的List.Fold和List.Foldback。我已经读了几本书,并试图在网上搜索一个简单的解释,但我仍然不明白。
-这不是重复的问题,在另一个链接中也没有得到回答。
答案 0 :(得分:3)
理解它的最好方法是举一个例子。假设您有一个数字列表,而您想找出总数。在命令式编程中,您可以执行以下操作:
let numbers = [ 19 ; 52 ; 35 ; 27]
let mutable total = 0
for n in numbers do
total <- total + n
printfn "%A" total // 133
这是一个很好的解决方案,但不起作用。让我们使用List.fold
做同样的事情:
numbers
|> List.fold (fun total n -> total + n) 0
|> printfn "%A" // 133
瞧!如果斜视,则可以在两个解决方案中识别相同的元素。
total
total + n
0
让我们看看List.fold
的签名:
val List.fold:
folder: 'State -> 'T -> 'State ->
state : 'State ->
list : 'T list
-> 'State
看看元素如何匹配?
List.foldBack
是相同的,但元素是按相反顺序进给的。参数的顺序也不同。
fold
的有趣之处之一是,在许多情况下,它可以代替尾部递归函数:
如果您没有List.fold
,并且想实现一个totalF
函数而又不可变,那么您将如何做呢?您将需要递归,最好是尾递归:
let rec totalF total ns =
match ns with
| [] -> total
| n :: tail -> totalF (total + n) tail
numbers
|> totalF 0
|> printfn "%A" // 133
同样,您可以像以前一样查看所有元素。实际上,如果我们将total + n
设为totalF
的参数:
let rec totalF f total ns =
match ns with
| [] -> total
| n :: tail -> totalF f (f total n) tail
numbers
|> totalF (fun total n -> total + n) 0
|> printfn "%A" // 133
您得到fold
,签名和使用方式相同:
val totalF:
f : 'a -> 'b -> 'a ->
total: 'a ->
ns : 'b list
-> 'a