使用方案中的闭包重新实现列表

时间:2014-11-24 18:30:41

标签: list scheme closures

这对我来说纯粹是一个好奇的问题:

因此,为了好玩,人们可以轻松地重新定义缺点,汽车和cdr:

(define cons+
  (lambda (a b)
    (lambda (f)
      (f a b)
  )))

(define car+
  (lambda (f)
    (f (lambda (a b) a))))

(define cdr+
  (lambda (f)
    (f (lambda (a b) b))))

这使用闭包创建列表的基本功能。在这种情况下,定义空列表的最佳方法是什么?

1 个答案:

答案 0 :(得分:4)

您需要作为空列表的特定特殊值;你只需要一些东西,然后把它当作空列表。在Common Lisp中,列表是缺点或符号NIL。您可以采用相同的方法并使用符号NIL,或者您可以使用其他一些值,只要您始终如一地对待它。 Lisp系列中链接列表的一部分美(有时是丑陋)是内涵数据结构。它们是由一些结构和许多惯例构建的。这就是为什么我们可以使用cons单元来实现单链表,树等等。

现在,一贯对待它意味着什么?其中一些将取决于您希望它的行为方式。在Common Lisp中,您可以使用空列表调用 car cdr ,然后您将返回空列表。在Scheme中,您将收到错误消息。在基于闭包的方法中,你有一个“漏洞”的抽象概念,你可以使用产生的值来调用 car + cdr + 缺点+ ,你可能得到一个值。

您想要什么界面?

在Lisp样式(conses和空列表)中实现单链表时,通常需要一个可以让您检查的界面:

(cons? (cons ...)) == true
(empty? empty)     == true

(就这些而言,您可以实施列表?

(define (list? x)
  (or (cons? x)
      (null? x)))

在您已经完成的工作之后,实现缺点功能应该不难。但是空?呢?你实际上在这里有很多自由。您可以实现空?,这样实际上有多个对象可用作空列表。只要合同有效,就可以了。

还有其他工作吗?

目前,您已经完成了有序对的工作实现,但它是leaky abstraction,因为某些未使用缺点创建的内容仍然可以传递给< strong> car 和 cdr 没有任何错误。你对公理很满意

(car (cons x y)) == x
(cdr (cons x y)) == y

但不是影响

  

(car z) == xz == (cons x _)
  (cdr z) == yz == (cons _ y)

如果您能找到一种方法来实现这些含义,那么汽车 cdr 仅适用于缺点生成的内容,则您可以弄清楚如何实现缺点?,并且可以使用相同的技术生成唯一的空列表对象。