Ocaml操纵列表

时间:2013-02-01 03:12:00

标签: list ocaml

真正的基本问题:我是Ocaml的新手,我在尝试操作列表时遇到了问题。我读过http://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html,遗憾的是我仍然感到困惑....我是函数式编程的新手。

如果我有以下功能:

  let stoverfl list1 list2 list3 =
      match list1 with
      |[]->None
      |h::list1 -> (*what I want to do goes in here*)

我想看一下list2和list3的第一个元素,比较它们,如果它们相等,将list3的第一个元素添加到list2,否则不要修改列表。我现在并不关心错误检查(即检查列表是否至少包含一个元素等)。

我的尝试:

 h::list1 -> let cmp1 = hd list2 (*this should return the first elemnt of list2??*)
             let cmp2 = hd list3
             if(cmp1=cmp2) then
                let updlist2 = concat list2 hd list3
                let updlist3 = hd list3
                (*pass updlist2 and updlist3 instead of list2 and list3 to next function*)
             else
                (*do nothing; pass list2 and list3 as normal*)

我觉得我做错了......任何建议都会受到赞赏! 感谢。

1 个答案:

答案 0 :(得分:1)

您说要将list3的第一个元素添加到list2。当一个功能程序员说出类似这样的东西时,他们想要构建一个如上所述的新列表。您无法实际修改list2 - 列表是不可变的,名称永久绑定到单个值。实际上,您似乎想要构建两个新列表。其中一个在list2前面有list3的第一个元素。另一个是list2的剩余部分(除了第一个元素之外)。

假设这就是你的意思,假设你并不担心列表是否为空,那么这是获取这些值的一种方法:

let updlist2 = List.tl list2 in
let updlist3 = (List.hd list2) :: list3

它实际上非常接近你所写的内容。

然而,我想知道你接下来会对这些值做些什么。如果您想将它们传递给另一个函数,那么将let s 置于 if之外更为正常。举个例子,这里有一些代码用列表或列表的尾部调用函数g,具体取决于列表的第一个元素:

let arg_for_g =
    match the_list with
    | [] -> []  (* No tail of the list *)
    | head :: tail -> if head = 3 then tail else the_list
in
    g arg_for_g

如果您将let放在if内,则需要对下一个函数编写两个不同的调用。这可能没问题,这取决于你将如何处理你的价值观。

(作为旁注,你应该担心列表是否为空!如果使用match语句,你可以很容易地检测到这种情况。)