首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用elisp实现流

用elisp实现流
EN

Stack Overflow用户
提问于 2015-03-11 05:58:31
回答 1查看 232关注 0票数 3

我正在阅读SICP书的3.5节,并试图使用Elisp实现流。本书使用Scheme语言实现流,如下所示:

流的核心结构是一个对,其car是序列的当前值,它的cdr是评估下一个项的承诺,它是通过以下结构实现的:

代码语言:javascript
复制
(define (cons-stream a b) (cons a (delay b)))

其中(delay b)等价于(lambda () b)

当计算这对的cdr时,它强制对流的延迟元素进行计算,这样我们就可以得到下一个元素,实现如下:

代码语言:javascript
复制
(define (stream-cdr stream) (force (cdr stream)))

其中(force delayed-object)只是(delayed-object)的执行。

有了这个构造,我们现在就可以透明地使用流构建递归过程,就好像它们是地图中的常规列表一样:

代码语言:javascript
复制
(define (stream-map proc stream)
    (if (stream-null? stream)
        the-empty-stream
      (cons-stream (proc (stream-car s))
                   (stream-map p (stream-cdr s)))))

我正在尝试使用Elisp编写类似的流实现,但我还没有找到实现delay的方法,因此它允许我以类似于Scheme的方式编写递归过程,目前我的解决方法是将延迟作为lambda表达式放在递归过程中,如下所示:

代码语言:javascript
复制
(defun stream-map (proc stream)
  (lexical-let ((p proc)
                (s stream))
    (if (stream-null? stream)
        the-empty-stream
      (cons-stream (funcall p (stream-car s))
                   (lambda ()
                     (stream-map p (stream-cdr s)))))))

显然不像方案的实现那么好。

以下是用于创建流的核心功能的Elisp版本:

代码语言:javascript
复制
(defun cons-stream (a b) (cons a b))
(defun stream-cdr (stream) (sicp-force (cdr stream)))
(defun sicp-force (exp) (funcall exp))

如何编写delay和其他流函数,这样就不必将lambda放入递归过程中?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-03-11 15:47:50

多亏了@Gerstmann的建议,我才能写出我正在寻找的建筑。新的实现现在看起来如下:

代码语言:javascript
复制
(setq the-empty-stream nil)
(defun stream-null? (s) (eq s the-empty-stream))
(defun my/sicp-delay (exp) `(lambda () ,exp))
(defun my/sicp-force (exp) (funcall exp))

(defmacro my/cons-stream (a b) (list 'cons a (my/sicp-delay b)))
(defun my/stream-car (stream) (car stream))
(defun my/stream-cdr (stream) (my/sicp-force (cdr stream)))

现在,我可以编写与方案实施一样干净的过程:

代码语言:javascript
复制
(defun my/stream-enumerate-interval (low high)
  (lexical-let ((l low)
                (h high))
    (if (> l h)
        the-empty-stream
      (my/cons-stream low
                      (my/stream-enumerate-interval (1+ l) h)))))

; this returns 12
(my/stream-car (my/stream-cdr (my/stream-cdr (my/stream-enumerate-interval 10 20))))
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28979606

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档