recursionschemeracketr5rs

Replaces occurrences in a list - Racket


I am writing a function called ptyper that takes a nested list, nl. This function replaces all occurrences of a number with n and all occurrences of a symbol with s. This is what I have now:

(define (ptyper nl) (cond
((null? nl) '())
((list? nl)
 (let ((ls (car nl)))
  (list (ptyper ls))))
((number? (car nl))
 (cons "n" (cdr nl)))
((symbol? (car nl))
 (cons "s" (cdr nl)))
(else
 (cons (car nl) (cdr nl)))))

I ran this test (ptyper '(2 (abc () "abc"))) but received an error that their was a contract violation. I'm not exactly sure what I'm doing wrong so if could use some help. Thanks!


Solution

  • Here is a possible solution with one function:

    (define (ptyper nl)
      (cond
        ((null? nl) '())      ; if the argument is an empty list, return the empty list
        ((list? nl)           ; if the argument is a list, then
         (let* ((c (car nl))  ; get its first element
                (nc (cond ((number? c) "n") ; transform it for numbers
                          ((symbol? c) "s") ; and symbols
                          ((list? c) (ptyper c)) ; if a list recur over it
                          (else c))))       ; otherwise (e.g. a string) return as it is
           (cons nc (ptyper (cdr nl)))))    ; recursive call on the rest of the list
        (else nl)))  ; this should never happen for the specification,
                     ; return the parameter or cause an error
    

    Note that the error in your case is caused by the recursive call. When the function is called on an atom, for instance 2, first it checks for null and list?, and those checks returns false. Then it checks for (number (car nl)), but nl is equal to 2 and so car fails.