真正的基本问题:我是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*)
我觉得我做错了......任何建议都会受到赞赏! 感谢。
答案 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
语句,你可以很容易地检测到这种情况。)