我需要一个函数,每次迭代递归返回(不打印)列表中的所有值。但是,每次我尝试编程时,我的函数都会返回一个列表。
let rec elements list = match list with
| [] -> []
| h::t -> h; elements t;;
每次在我写的另一个函数中返回时,我都需要使用每个元素,所以我一次需要这些元素,但我无法弄清楚这一部分。任何帮助将不胜感激。
答案 0 :(得分:3)
您的功能相当于:
let rec elements list =
match list with
| [] -> []
| h :: t -> elements t
这是因为a ; b
评估a
(并丢弃结果),然后评估并返回b
。显然,这相当于:
let elements (list : 'a list) = []
这不是一个非常有用的功能。
但是,在尝试解决此问题之前,请理解目标Caml函数只能返回一个值。返回多个值是不可能的。
有办法解决这个限制。一种解决方案是将您希望返回的所有值打包成单个值:通常是元组或列表。因此,如果您需要返回任意数量的元素,您可以将它们一起打包到一个列表中,并拥有列出的调用代码进程:
let my_function () = [ 1 ; 2; 3; 4 ] in (* Return four values *)
List.iter print_int (my_function ()) (* Print four values *)
另一种不太常见的解决方案是提供一个函数并在每个结果上调用它:
let my_function action =
action 1 ;
action 2 ;
action 3 ;
action 4
in
my_function print_int
这比返回列表更灵活,但可能更快:列表可以过滤,排序,存储...
答案 1 :(得分:1)
您的问题有点令人困惑 - 您需要一个能够返回列表中所有值的函数。那么返回可变数量值的最简单方法是使用列表!您是否可能尝试模拟Python生成器? OCaml与yield
没有任何相似之处,但通常通过将函数“传递”到值(使用iter
,fold
或map
)来完成相同的操作。
您目前所编写的内容与Python相同:
def elements(list):
if(len(list) == 0):
return []
else:
list[0]
return elements(list[1:])
如果您尝试这样做:
def elements(list):
if(len(list) > 0):
yield list[0]
# this part is pretty silly but elements returns a generator
for e in elements(list[1:]):
yield e
for x in elements([1,2,3,4,5]):
dosomething(x)
OCaml中的等价物将是这样的:
List.iter dosomething [1;2;3;4;5]
如果您要确定列表a是否是列表b的子集(正如我从您的评论中收集的那样),那么您可以利用List.mem
和List.for_all
:
List.for_all (fun x -> List.mem x b) a
fun x -> List.mem x b
定义了一个函数,如果值x等于(是b的成员)中的任何元素,则该函数返回true。 List.for_all
接受一个返回bool的函数(在我们的例子中,我们刚刚定义的隶属函数)和一个列表。它将该函数应用于列表中的每个元素。如果该函数对列表中的每个值都返回true,则for_all
将返回true。
所以我们所做的是:对于a中的所有元素,检查它们是否是b的成员。如果您对如何自己编写这些函数感兴趣,那么我建议您阅读list.ml的源代码,其中(假设* nix)可能位于/ usr / local / lib / ocaml或/ usr / lib / ocaml。< / p>