在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))))
非常感谢所有帮助。
答案 0 :(得分:5)
不,您不需要流来制作循环列表。
创建循环列表有两种方法,标准Scheme方法和Racket方法(因为Racket的conses是不可变的)。我将使用SRFI 1的circular-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
函数来处理周期。非常漂亮。 : - )