定义于列表上的函数

LISP是LISt Processing的缩写, 这显然暗示了LISP必然包含许多和列表有关的函数, 让我们现在就来检视一些.

最简单的函数大概就是length (尽管一个实际的实现里的length并不会那么简单, 因为它还要考虑"环路"的情况), 它大概可以定义如下.

以下是一些例子.

另外一个很简单的函数是list-ref, 它取出列表某个位置的元素, 以下是一种可能的定义.

然后是一些例子.

现在让我们来引入memq, memv和member, 但首先我们应该讨论一下谓词eq?, eqv?和equal?.

eq?, eqv?和equal?是Scheme中三种不同的判断相等性的谓词. 现在因为读者对于Scheme的理解还不够深入, 即便直截了当地讨论它们的区别, 或许也是没有益处的. 但读者可以这么区分它们, equal?是外延等价的近似物, eq?是内涵等价的近似物, eqv?是用来补充eq?的, 也是内涵等价的近似物. 比如, 请看以下例子.

之所以会出现这样的情况, 是因为每次cons创建的都是"不同"的序对对象.

就此打住.

memq, memv和member仅仅是所用相等谓词不同而已, 其余都是一样的.

一种可能的memq定义如下.

它可以用来判断一个元素是否在列表中, 以下是一些例子.

正如名字所暗示的那样, memq用eq?比较相等, memv用eqv?, member用equal?.

接着, 让我们来看assq, assv和assoc.

在Scheme上下文中, 元素均为序对的列表被称为关联表 (association list), 它可以用来表示对应关系 (的外延).

以下是assq的一种可能定义.

注记.

这也可以类推到c和r之间隔着3个4个a或d的情况. 但是更多, Scheme标准就不保证了.

接下来是一些例子.

也就是说, assq可以根据每个序对的car部分 (一般被称为键) 进行索引.

练习.  编写过程assp, 它接受一个谓词和一个关联表, 然后返回第一个"键满足谓词"的序对, 如果这样的序对不存在, 就返回#f. 以下是一些例子.

symbol?判断一个对象是否是符号, 类似的还有number?, pair?, procedure?等.

你的回應