【发布时间】:2013-06-29 07:41:09
【问题描述】:
我在 Lisp (Scheme) 中开发了一个纯函数式队列,如下所示:
;Internal functions
(define (delay-cons x s)
(cons x (lambda () s)))
(define (delay-car s)
(car s))
(define (delay-cdr s)
((cdr s)))
(define (delay-append s t)
(if (null? s)
t
(delay-cons (delay-car s) (delay-append (delay-cdr s) t))))
;API
(define (enqueue x q) (delay-append q (delay-cons x empty)))
(define dequeue delay-cdr)
(define peek delay-car)
(define empty '())
(define empty? null?)
delay-cons 类似于 cons,但它通过将尾部包装在闭包中来暂停对尾部的评估。 delay-append 类似地(delay-append s t)通过尾部的递归悬挂将 t 附加到 s。
因此,每个入队都包裹一层闭包,使其成为 O(1),每个 peek 只需检索一个使其成为 O(1) 的值,每个出队检索并评估一个闭包,使其成为 O(1)。
我在其他地方没见过这个;例如,在 Okasaki 的 Purely Functional Data Structures 中,最简单的队列是银行家队列,它比这复杂得多,并且只有分期 O(1) 的入队、窥视和出队。这让我怀疑我的推理有误。
这个数据结构合理吗?在某处有它的参考吗?
编辑: delay-cons 在 delay-append 中使用是错误的;我正在尝试使用宏之类的函数(感谢 Will Ness)。
我尝试使用
来纠正它(define (delay-append s t)
(if (null? s)
t
(cons (delay-car s) (lambda () (delay-append (delay-cdr s) t)))))
但这不适用于 API。
【问题讨论】:
-
也许你应该提出断言、测试和示例来检查你做了什么。特别是不清楚这提供了什么样的“延迟”以及“延迟-cons”实际上做了什么——考虑到Scheme做了严格评估。
-
您的编辑破坏了它。之前还可以。
-
谢谢威尔,它做到了;我试图弥补延迟问题的错误(我试图使用宏之类的函数) - 入队是 O(N) 所写的。
-
不。再次打破它。
delay-cons不会延迟任何事情,因为它是一个函数,所以在评估它的主体之前计算它的参数。你的新delay-append很简单append。 -
原定义有效:
(define x (delay-append (delay-cons 1 ()) (delay-cons 2 ()))) => ;Value: x--(delay-car x) => ;Value: 1--(delay-car (delay-cdr x)) => ;Value: 2--(delay-cdr (delay-cdr x)) => ;Value: ()
标签: data-structures functional-programming scheme queue purely-functional