scheme - Changing a function into CPS style -
we asked write procedure when given list replace first occurrence of given element , first, catch write in cps style. unable turn cps style written procedure given success-cont , fail-cont..
if willing give try appreciate :]
the procedure have (graciously provided answers here):
(define (replace-one list old new) (cond ((pair? list) (let ((next (replace-one (car list) old new))) (cons next (if (equal? next (car list)) ; changed? (replace-one (cdr list) old new) ; no, recurse on rest (cdr list))))) ; yes, done ((eq? list old) new) (else list)))
edited
a big @willness pointing out , fixing bug, lurking in original code. here's corrected implementation based on code (with stepwise derivation), commented , made idiomatic racket:
(define (replace-one lst b) (let loop ([lst lst] ; input list [f #f] ; have made first replacement? [k (lambda (ls f) ls)]) ; continue results: list , flag (cond (f ; replaced already: (k lst f)) ; continue without changing ((empty? lst) ; empty list case (k lst f)) ; go on empty lst , flag ((not (pair? lst)) ; - none replaced yet - atom? (if (eq? lst a) ; atom being searched? (k b #t) ; replace, continue updated flag (k lst f))) ; no match, continue (else ; list? (loop (first lst) ; process `car` of `lst` f ; according flag's value, , (lambda (x f) ; accept resulting list , flag, , (loop (rest lst) ; process `cdr` of `lst` f ; according new value of flag, (lambda (y f) ; getting results that, , (if f ; - if replacement made - (k ; continuing new list, built (cons x y) ; results of processing 2 branches, f) ; , new flag, or (k lst f)))))))))) ; old list if nothing changed
notice single success continuation used (called k
in code above) accepts two resulting values: list , flag. initial continuation returns final resulting list, , discards final flag value. return flag, indication of whether replacement have been made @ or not. used internally preserve of original list structure possible, usual persistent data types (as seen in answer).
finally, test code:
; fixed, wasn't working correctly (replace-one '((((1 2) 3 4) a) 6) 'a 'b) => '((((1 2) 3 4) b) 6) (replace-one '(((-))) '- '+) => '(((+))) (replace-one '((-) - b) '- '+) => '((+) - b) (replace-one '(+ 1 2) '+ '-) => '(- 1 2) (replace-one '((+) 1 2) '+ '-) => '((-) 1 2) (replace-one '(1 2 ((+)) 3 4) '+ '-) => '(1 2 ((-)) 3 4) (replace-one '() '+ '-) => '() (replace-one '(1 2 ((((((+ 3 (+ 4 5)))))))) '+ '-) => '(1 2 ((((((- 3 (+ 4 5))))))))
Comments
Post a Comment