1

在 Scheme/Lisp 中,我试图创建一个将列表转换为循环列表的函数。因此,我认为我需要构建一个无限流,其中列表的尾部指向列表的头部。

到目前为止,这是我的代码:

(define (rotate-list l1 l1copy)
  (if (null? (force (cdr l1)))
      (cons (car l1) (delay l1copy)))
      (cons (car l1) (delay (rotate-list (force (cdr l1)) l1copy))))

非常感谢所有帮助。

4

1 回答 1

5

不,您不需要流来制作循环列表。

有两种创建循环列表的方法,标准 Scheme 方法和 Racket 方法(因为 Racket 的 conses 是不可变的)。我将查看使用SRFI 1circular-list函数的示例。这是参考实现:

(define (circular-list val1 . vals)
  (let ((ans (cons val1 vals)))
    (set-cdr! (last-pair ans) ans)
    ans))

这样做是在给定值列表中找到最后一对,并将set-cdr!其返回到该列表的开头。很简单,对吧?

在 Racket 中,conses 是不可变的,因此set-cdr!不存在。因此,Racket 是这样做的:

(define (circular-list val1 . vals)
  (let ([ph (make-placeholder #f)])
    (placeholder-set! ph
      (cons val1 (let loop ([vals vals])
                   (if (null? vals)
                     ph
                     (cons (car vals) (loop (cdr vals)))))))
    (make-reader-graph ph)))

这使用 Racket 的make-reader-graph功能来处理循环。非常漂亮。:-)

于 2013-02-04T02:28:44.830 回答