Reputation: 71
Going further for the scheme how do you sum numbers in a list when you have structures and list of lists now i want to replace all occurrences of atom a1 in SEXP with atom a2.
For example,
(replace (list (list 'a 'b) (list 1 3 )) 'a 'b) =>
(list (list 'b 'b) (list 1 3))
(replace (list (list 'a 'b) (list 1 3)) 1 2) =>
(list (list 'a 'b) (list 2 3))
;; An ATOM is one of:
;; -- Symbol
;; -- String
;; -- Number
(define-struct SEXP (ATOM SEXP))
;; An SEXP (S-expression) is one of:
;; -- empty
;; -- (cons ATOM SEXP)
;; -- (cons SEXP SEXP)
My code,
;; replace: Atom atom sexp -> sexp
(define (replace a1 a2 sexp)
(cond
[(empty? sexp) empty]
[(SEXP? sexp)
(cons (replace a1 a2 (first sexp)) (replace a1 a2 (rest sexp)))]
[else
(cond
[(or (symbol=? (first sexp) a1)
(string=? (first sexp) a1)
(= (first sexp) a1))
(cons a2 (replace a1 a2 (rest sexp)))]
[else (cons (first sexp) (replace a1 a2 (rest sexp)))])]))
for the part to determine if it is a1, do we need call a helper function we could do so in my way present here?
Also, since sexp is a list of lists and atom is flat,
(symbol=? (first sexp) a1)
might cause problem since scheme would expect a symbol but given (list xxxxxx)
How do you fix that problem as well?
Upvotes: 0
Views: 134
Reputation: 236004
The code can be simplified a great deal if we make sure that the equality comparison is performed only when we're sure that sexp
is an atom, try this:
(define (replace a1 a2 sexp)
(cond
[(empty? sexp) empty]
[(SEXP? sexp) ; (define SEXP? pair?)
(cons (replace a1 a2 (first sexp))
(replace a1 a2 (rest sexp)))]
[(equal? sexp a1) a2]
[else sexp]))
The same comments to your previous question apply, though: you must be consistent, and if you're using SEXP
structs then you must stick to using that struct's accessor procedures, instead of first
, rest
, etc. Also notice how we can use equal?
for comparisons when we don't know beforehand the specific type of the elements. Test it like this, and notice the correct order of the parameters:
(replace 'a 'b (list (list 'a 'b) (list 1 3)))
=> '((b b) (1 3))
(replace 1 2 (list (list 'a 'b) (list 1 3)))
=> '((a b) (2 3))
Upvotes: 1