为什么OCaml只有first :: rest on list,但不是rest :: last for list?

时间:2013-02-02 11:28:07

标签: functional-programming ocaml

在OCaml中,对于列表,我们总是first::rest。从列表中获取第一个元素或在列表前插入元素很方便。

但为什么OCaml没有rest::last?如果没有List的函数,我们就不能轻易地获取列表的最后一个元素或将元素插入到列表的末尾。

2 个答案:

答案 0 :(得分:8)

list数据类型不是魔法内置函数,只是具有一些语法糖的常规递归数据类型。您可以使用Nil代替[]Cons(first,rest)代替first::rest自行实施,方法如下:

type 'a mylist =
  | Nil
  | Cons of 'a * 'a mylist

我不确定你是否会将上面的定义看作是对你问题的回答,但实际上是:当你写first::rest时,你没有调用函数,你只是使用了构建新值的数据类型构造函数(在恒定的时间和空间中)。

这个定义很简单,并且具有明确的算法属性:列表是不可变的,访问列表的第一个元素是O(1),访问k - 元素是O(k),连接两个列表li1li2O(length(li1))等。特别是,访问最后一个元素或在列表li末尾添加内容将是O(length(li)) ;我们并不急于将其视为一种方便的操作,因为它很昂贵。

如果要在序列末尾添加元素,则列表不是正确的数据结构。您可能希望使用队列(如果您遵循先进先出访问规则),deque等。标准库中有(可变)Queue结构,并且两个第三方叠加CoreBatteries都有一个deque模块(在电池中持久存在,在Core中可变)。

答案 1 :(得分:5)

因为列表只是定义为

的普通数据类型
type 'a list = Nil | Cons of 'a * 'a list

除了您将Nil拼写为[]Cons拼写为中缀::。换句话说,如果你愿意,列表是“单链接”的。除了构造函数的语法之外,没有任何魔法。显然,要获得最后一个元素,或者附加一个元素,那么你需要一些辅助函数。