List.rev表现得很奇怪吗?

时间:2012-03-06 19:20:26

标签: list functional-programming append ocaml reverse

我是OCaml的新手并尝试将List.append作为一项学习练习。这就是我所拥有的:

let rec append a b =
    match (List.rev a) with
       []       -> b
       | x:: xs -> append xs (x::b)

这似乎有效,直到参数a有两个以上的元素。例如:

# append [1;2] [3;4] 
- : int list = [1; 2; 3; 4]
# append [1;2;3] [4;5;6]
- : int list = [2; 1; 3; 4; 5; 6]

这里发生了什么?我已经检查过了,List.rev [1;2;3]会返回int list = [3; 2; 1]。我知道我的实现是天真的,而不是(还)懒惰,但它似乎应该有效。

1 个答案:

答案 0 :(得分:11)

如果您考虑一下,那么您正在颠倒第一个列表很多次。可能比你想要的更多。

如果您按照示例的步骤操作,可以看到发生了什么。

append [1; 2; 3] []
(* match binds x to 3, xs to [2; 1] *)
append [2; 1] [3]
(* match binds x to 1, xs to [2] *)
append [2] [1; 3]
(* match binds x to 2, xs to [] *)
append [] [2; 1; 3]
(* done *)