List.fold_left
确实迭代一个列表,将值从一个调用传递到另一个调用,这基本上就像一个斗旅 https://en.wikipedia.org/wiki/Bucket_brigade,只有一个桶,在每次迭代中,您都可以查看桶中的内容,取出其中的所有内容并放入新的内容。
更正式地说,fold_left f init elements
有类型
val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a
它需要三个参数,函数f
,初始值init
,以及一个列表elements
。功能f
为每个元素调用x
of elements
as f acc x
, where acc
或者是init
if x
是列表的第一个元素或先前调用返回的结果f
。回到我们的类比,它要么是初始的空桶,要么是链中上一个调用传递的桶。
在您的情况下,存储桶的作用是所有项的最终总和。最初,它是空的,然后每个新项计算(fst e) * (pow x (snd e))
并将其添加到存储桶中,这样最后您将得到所有项的总和,
let polynomial coeffs x =
List.fold_left (fun sum (k,r) -> sum + k * pow x r) 0 coeffs
请注意,不要使用fst
and snd
为了访问该对的元素,我直接在参数列表中解构了元组。这使得代码更容易理解并且更短。
应用于每个步骤的函数有两个参数,sum
是桶(通常称为“累加器”)和列表的元素,它是一对(k,r)
在我们的例子中。我们乘以k
的值x
变量的幂r
然后我们将结果添加到累加器中。
For people with an imperative mindset the following pseudocode1 might be more insightful than the bucket brigade analogy:
def fold_left(user_func, init, elements):
acc = init
for elt in elts:
acc = user_func(acc, elt)
return acc
1) Any resemblance to Python is purely coincidental :)