自从我上次在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
为空列表)。
感谢您的帮助!
答案 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,他们引入了不可变对作为标准。这意味着您无法设置car
或cdr
,除非它由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))