Ocaml 如何使用List.fold_left?
我仍在努力理解左折叠是如何工作的。它是否像Ocaml 如何使用List.fold_left?,ocaml,Ocaml,我仍在努力理解左折叠是如何工作的。它是否像list.iter那样遍历列表?还是我的代码有其他问题?我认为e是列表中的元素(因此它是一个元组),fst e取元组中的第一个元素,snd e取元组中的第二个元素 let rec pow x n = if n < 0 then 0 else if n = 0 then 1 else x * pow x (n - 1);; let polynomial lst =
list.iter
那样遍历列表?还是我的代码有其他问题?我认为e是列表中的元素(因此它是一个元组),fst e
取元组中的第一个元素,snd e
取元组中的第二个元素
let rec pow x n =
if n < 0 then
0
else if n = 0 then
1
else
x * pow x (n - 1);;
let polynomial lst = function
| x -> List.fold_left (fun e -> (fst e) * (pow x (snd e))) 1 lst;;
让rec pow x n=
如果n<0,则
0
否则,如果n=0,则
1.
其他的
x*功率x(n-1);;
设多项式lst=函数
|x->List.fold_左(fune e->(fst e)*(pow x(snd e)))1lst;;
lst是一个元组列表,其中每个元组有两个整数并构成一个多项式函数,因此多项式应该返回一个函数。因此,应该发生的一个例子是
# let f = polynomial [3, 3; -2, 1; 5, 0];;
val f : int -> int = <fun>
# f 2;; (* f is the polynomial function f(x) = 3x^3 + (-2)x + 5 *)
- : int = 25
#设f=多项式[3,3;-2,1;5,0];;
val f:int->int=
#f2;;(*f是多项式函数f(x)=3x^3+(-2)x+5*)
-:int=25
但是我收到了这个错误信息
错误:此表达式的类型为int,但表达式的类型应为'a->int*int'
List.fold_left
确实在一个列表上迭代,将值从一个调用传递到另一个调用,这基本上就像一个,只有一个bucket,在每次迭代中,您可以查看bucket,获取其中的任何内容并放入新的内容
更正式地说,fold_left f init元素具有类型
val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a
它有三个参数,函数f
,初始值init
,以及元素列表。函数f
为元素的每个元素x
调用为f acc x
,其中acc
是init
,如果x
是列表的第一个元素,或者是先前调用f
返回的结果。回到我们的类比,它要么是初始空桶,要么是链中上一次调用传递的桶
在您的案例中,bucket的角色是所有术语的最终总和。最初,它是空的,然后每个新术语计算(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
和snd
访问该对的元素,而是直接在参数列表中解构元组。这使得代码更容易理解和缩短
应用于每个步骤的函数有两个参数,sum
是bucket(通常称为“累加器”)和列表元素,在我们的例子中是一对(k,r)
。我们将k
乘以提升到幂r
的x
变量的值,然后将结果添加到累加器中
对于具有命令式思维的人来说,以下伪代码1可能比桶旅类比更具洞察力:
def fold_left(user_func, init, elements):
acc = init
for elt in elts:
acc = user_func(acc, elt)
return acc
1) 与Python的任何相似之处纯粹是巧合:)列表。fold_left
确实在列表上迭代,将值从一个调用传递到另一个调用,这基本上就像一个,只有一个bucket,在每次迭代中,您可以查看bucket,获取其中的任何内容并放入新的内容
更正式地说,fold_left f init元素具有类型
val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a
它有三个参数,函数f
,初始值init
,以及元素列表。函数f
为元素的每个元素x
调用为f acc x
,其中acc
是init
,如果x
是列表的第一个元素,或者是先前调用f
返回的结果。回到我们的类比,它要么是初始空桶,要么是链中上一次调用传递的桶
在您的案例中,bucket的角色是所有术语的最终总和。最初,它是空的,然后每个新术语计算(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
和snd
访问该对的元素,而是直接在参数列表中解构元组。这使得代码更容易理解和缩短
应用于每个步骤的函数有两个参数,sum
是bucket(通常称为“累加器”)和列表元素,在我们的例子中是一对(k,r)
。我们将k
乘以提升到幂r
的x
变量的值,然后将结果添加到累加器中
对于具有命令式思维的人来说,以下伪代码1可能比桶旅类比更具洞察力:
def fold_left(user_func, init, elements):
acc = init
for elt in elts:
acc = user_func(acc, elt)
return acc
1) 与Python的任何相似之处纯粹是巧合:)因此0是函数的起始值,并且(fun sum(k,r)->sum+k*pow x r)将其相加?如果我没有弄错的话。不客气,我已经添加了一个详细的fold_left
函数说明,因为官方手册中似乎没有详细描述它。所以0是函数的起始值,并且(fun sum(k,r)->sum+k*pow x r)添加了它?如果我没有弄错的话。不客气,我已经添加了一个关于左折
功能的详细说明,因为官方手册中似乎没有详细描述它。