使用list.fold\u right反转列表

使用list.fold\u right反转列表,list,ocaml,List,Ocaml,我最近刚开始学习ocaml,现在遇到了一个问题,我想使用list.fold\u right将列表(即[1;2;3]转换为[3;2;1]) 从我迄今为止的尝试: 据我了解, List.fold_right (fun x y -> x+y) [1;2;3] 0 将导致1+(2+(3+0)) 所以我想我可以通过这样做来扭转这个列表 List.fold_right (fun x y -> y::x) [1;2;3] [] 理论上应该给我 1掉期(2掉期(3掉期[])转换为1掉期([]32

我最近刚开始学习
ocaml
,现在遇到了一个问题,我想使用
list.fold\u right
将列表(即
[1;2;3]
转换为
[3;2;1]

从我迄今为止的尝试:

据我了解,

List.fold_right (fun x y -> x+y) [1;2;3] 0
将导致
1+(2+(3+0))

所以我想我可以通过这样做来扭转这个列表

List.fold_right (fun x y -> y::x) [1;2;3] []
理论上应该给我

1掉期(2掉期(3掉期[])
转换为
1掉期([]32)
,最终成为
3掉期1

然而,这里似乎存在类型不匹配

另外,如果我将函数更改为
(funxy->y@x)
,我能够成功地将列表中的列表反转(即
[[1];[2];[3]]
[[3];[2];[1]]


这里发生了什么?

您想将列表项添加到累积列表的末尾。通常只能对列表的开头进行操作,因此不能使用cons(
)运算符。但您可以将该项视为一个列表,并将它们连接在一起(
@
)。只是两个操作数都需要是列表,所以将要添加的项放在列表中

List.fold_right (fun x acc -> acc @ [x]) [1; 2; 3] []

List.fold_right
的类型是
('a->'b->'b)->'a List->'b->'b
。如果查看要折叠的函数的类型,它是
'a->'b->'b
。换句话说,第一个参数是输入列表的新元素,第二个参数是累积答案。在您的例子中,第一个参数是int(比如说),第二个参数是int的列表。这就是为什么不能使用
(funxy->y::x)
。第一个参数
x
是下一个int(不是列表)

如果您查看示例表达式1+(2+(3+0)),这实际上是一个很好的思考方式,您将看到,以这种方式反转列表是非常困难的。函数处理的第一个值应该位于结果的前面。这不是处理列表的自然方式。用
list.fold\u left
反转列表要容易得多(事实上,这很简单)

如果您真的想这样做,您需要做的是将每个新值添加到累积结果的末尾。这不是不可能的,这只是一种处理列表的糟糕方式。下面是一个向列表末尾添加值的函数:

let add_to_end x l = l @ [x]
所以我想我可以通过这样做来扭转这个列表

List.fold_right (fun x y -> y::x) [1;2;3] []
List.fold_right(fun x y->y::x)[1;2;3][]
理论上应该是 给我

1个掉期(2个掉期(3个掉期[])转换为1个掉期([]3个掉期),最终 变成3 2 1

首先,在
List.fold_right(fun x y->y::x)[1;2;3][]
,最初,
y是[]
x是3
,在这种情况下,你不能做
y::x
,也就是说,你不能做
[]::3

您所说的交换是什么意思


正如其他答案所示,您必须提供一个
append
函数。

啊,我理解。当我进行连接时,它将采用[some list]和一个元素的形式,因此我显然不能执行list::element,因此我必须使用list@[element]进行连接。我本来不清楚。谢谢