将元素添加到OCAML中的循环列表中 [英] Add elements to list in a loop in OCAML

查看:76
本文介绍了将元素添加到OCAML中的循环列表中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我是OCAML的初学者,我想创建一个函数以在列表的末尾添加元素并返回此列表.这是我的代码:

Hi i'm a beginner in OCAML and i would like to create a function to add elements a the end of a list and return this list. Here is my code :

let test () : int list =
  let mylist = [] in
    for i = 1 to 3 do
      mylist@[i];
    done;
mylist;;

它说mylist @ [i]应该具有单位类型.当我调用此函数时,它将返回一个空列表.谁能帮我 ?谢谢

It says that mylist@[i] should have type unit. When I call this function it returns an empty list. Can anyone help me ? Thanks

推荐答案

Ocaml列表是不可变的,即不能更改.表达式

Ocaml lists are immutable, i.e., they cannot be changed. The expression

mylist@[i]

创建一个新列表.但是,由于您对结果不执行任何操作,因此将其丢弃.如果要构建这样的列表,则需要将其存储在引用中.

creates a new list. However, since you do nothing with the result, it is just thrown away. If you want to build a list like that, you need to store it in a reference.

let l = ref [] in
for i = 0 to 3 do
  l := !l @ [i]
done;
List.iter (fun item -> print_int item; print_newline ()) !l

但是,我建议您不要那样做.追加两个列表是相当昂贵的操作,因为会创建一个新列表,并且每次都会复制所有元素.一种更有效的方法是按照相反的顺序创建列表,并使用List.cons(::运算符),这会将新元素添加到列表的开头.

I would recommend you, however, not to do it that way. Appending two lists is a rather expensive operation, because a new list is created and all elements are copied every time. A much more efficient way to do what you want is to create the list in reverse order and use List.cons (the :: operator), which adds new elements to the beginning of the list.

let l = ref [] in
for i = 3 downto 0 do
  l := i :: !l
done;
List.iter (fun item -> print_int item; print_newline ()) !l

cons操作以恒定的时间运行,因为它可以重用已经存在的列表.

The cons operation runs in constant time, because it can reuse the already existing list.

或者,您也可以使用递归创建列表.

Alternatively, you can also create the list using recursion.

let rec l i =
  if i <= 3 then i :: l (i+1) else [] in
List.iter (fun item -> print_int item; print_newline ()) (l 0)

此变体也不需要复制,但它不是尾递归的,即,它使用的堆栈空间与列表中的元素一样多.

This variant also needs not copying, but it is not tail-recursive, i.e., it uses as much stack space as elements in the list.

let rec l acc i =
  if i >= 0 then l (i :: acc) (i-1) else acc in
List.iter (fun item -> print_int item; print_newline ()) (l [] 3)

此变体高效,尾递归,但较难阅读(IMHO).

This variant is efficient, tail-recursive, but harder to read (IMHO).

最后,您可能要查看队列模块 ExtLib中的DynArray模块在电池中.

As a final remark, you might want to check out the Queue module or the DynArray module in ExtLib or in Batteries.

这篇关于将元素添加到OCAML中的循环列表中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆