It has been a while since i last programmed in Racket. Now i wanted to make a circular list in Racket as follows :
(define x (list 1 2))
(set-mcdr! (cdr x) x)
But this gives rises to the error :
set-mcdr!: contract violation
expected: mpair?
given: '(2)
argument position: 1st
other arguments...:
'(1 2)
I'm surprised because (cddr x)
is '()
so I don't understand why he tells me "expected: mpair?" as '(2)
is a pair (with cdr
the empty list).
Thanks for your help!
The list must be mutable if you want set-mcdr!
to work, and all procedures used must also operate on mutable pairs; please check the documentation and notice that all the procedures contain an m
as part of their name. For example, try this:
(require racket/mpair)
(define x (mlist 1 2))
(set-mcdr! (mcdr x) x)
Other answers are of course entirely correct. I'd like to add, though, that there might be a different data structure that serves your needs better! I would take a look at in-cycle
:
#lang racket
(define cyclic-sequence
(in-cycle (list 3 4 5)))
(for/list ([elt cyclic-sequence]
[i (in-range 13)])
elt)
Since you worked with Racket they introduced immutable pairs as standard. That means you cannot set car
or cdr
unless it's contructed of mcons
.
However, in the SRFI-1 there is a constructor that makes circular lists and makes the list compatible with all procedures in #!racket that expects immutable lists:
#!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))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.