Racket中的循环列表

时间:2015-02-06 15:49:16

标签: list racket

自从我上次在Racket编程以来已经有一段时间了。 现在我想在Racket中制作一个循环列表如下:

(define x (list 1 2))
(set-mcdr! (cdr x) x)

但这会导致错误:

set-mcdr!: contract violation
expected: mpair?
given: '(2)
argument position: 1st
other arguments...:
 '(1 2)

我很惊讶因为(cddr x)'()所以我不明白为什么他告诉我“预期:mpair?”因为'(2)是一对(cdr为空列表)。

感谢您的帮助!

3 个答案:

答案 0 :(得分:3)

如果您希望set-mcdr!工作,则列表必须是 mutable ,并且所有使用的过程也必须在可变对上运行;请检查documentation并注意所有程序都包含m作为其名称的一部分。例如,试试这个:

(require racket/mpair)

(define x (mlist 1 2))
(set-mcdr! (mcdr x) x)

答案 1 :(得分:2)

其他答案当然完全正确。不过,我想补充一点,可能会有不同的数据结构更好地满足您的需求!我会看一下in-cycle

#lang racket

(define cyclic-sequence 
  (in-cycle (list 3 4 5)))

(for/list ([elt cyclic-sequence]
           [i (in-range 13)])
  elt)

答案 2 :(得分:0)

由于您使用Racket,他们引入了不可变对作为标准。这意味着您无法设置carcdr,除非它由mcons构成。

但是,在SRFI-1中有一个构造函数可以创建循环列表,并使列表与#!racket中所有需要不可变列表的过程兼容:

#!racket

(require srfi/1)
(circular-list 1 2 3) ; ==> #0=(1 2 3 . #0#)

;; alternatively you can make a list circular
(apply circular-list '(1 2 3)) ; ==> #0=(1 2 3 . #0#)

(map cons '(1 2 3 4 5 6) (circular-list #t)) 
; ==> ((1 . #t) (2 . #t) (3 . #t) (4 . #t) (5 . #t) (6 . #t))