Reputation: 39
I was trying to define a replace procedure that basically does the same thing as the list-set. This is my code so far:
(define replace
(lambda (s pos lst fin-lst)
(cond
((zero? pos) (cons (cons (reverse fin-lst) s) (rest lst)))
(else (replace s (- pos 1) (rest lst) (cons (first lst) fin-lst))))))
It sort of does what it's supposed to but I'm struggling to have the output look the way I want it to. For example this is the result I want
(replace 'a 2 '(1 2 3 4 5) '()) => '(1 2 a 4 5)
But as of now, this is what my procedure returns
'(((1 2) . a) 4 5)
I understand this is due to the cons vs. append, but how can I change my code to get rid of the extra parentheses and . ?
Upvotes: 1
Views: 442
Reputation: 15793
try this:
(define replace
(lambda (l pos e)
((lambda (s) (s s l pos (lambda(x) x)))
(lambda (s l i col)
(if (null? l)
(col '())
(if (zero? i)
(col (cons e (cdr l)))
(s s (cdr l) (- i 1)
(lambda (r)
(col (cons (car l) r))))))))))
(replace '(a b c d e f) 2 'x)
(replace '(a b c d e f) 0 'x)
(replace '(a b c d e f) 20 'x)
Upvotes: 0
Reputation: 236004
You almost had it! The reverse
call is misplaced, and you need to use append
to stick the two lists together. This is what I mean:
(define replace
(lambda (s pos lst fin-lst)
(cond
((zero? pos)
(append (reverse (cons s fin-lst)) (rest lst)))
(else
(replace s (- pos 1) (rest lst) (cons (first lst) fin-lst))))))
It works as you expected:
(replace 'a 2 '(1 2 3 4 5) '())
=> '(1 2 a 4 5)
Upvotes: 1