Search code examples
racketabstraction

Recursion and Abstraction Error in Racket


I currently have a function that is supposed to return the largest value in a supplied list. I provide the function with a list and a value function and expected the greatest value to return as shown in the tests. The error I keep running into is in the second branch of the cond clause. Although my first test passes, my second test does not, receiving an error that says the > function expects a real number but is given a string. I am not sure why this error keeps happening, because the supplied string-length function is meant to convert every string in the list into a number for its value.

; list-superlative : [NE-List-of X] (X -> X) -> X
; returns the maximum valued element in a non-empty
; list of elements

(check-expect
 (list-superlative
  (cons "hello" (cons "hi" (cons "hey" '())))
  string-length)
 "hello")

(check-expect
 (list-superlative
  (cons 1 (cons 2 (cons 3 '())))
  identity)
 3)

(define (list-superlative nelox vf)
   (cond
    [(empty? (rest nelox)) (first nelox)]
    [(cons? (rest nelox))
     (if
      (> (vf (first nelox))
         (list-superlative (rest nelox) vf))                <--- error occurs in this line
      (first nelox) (list-superlative (rest nelox) vf))]))

Solution

  • You need to apply the vf extractor procedure to the result of the recursive call as well. This should fix it:

    (define (list-superlative nelox vf)
      (cond
        [(empty? (rest nelox)) (first nelox)]
        [(cons? (rest nelox))
         (if (> (vf (first nelox))
                (vf (list-superlative (rest nelox) vf))) ; fix this line
             (first nelox)
             (list-superlative (rest nelox) vf))]))
    

    It works as expected:

    (list-superlative
     (cons "hello" (cons "hi" (cons "hey" '())))
     string-length)
    ; "hello"
    
    (list-superlative
     (cons 1 (cons 2 (cons 3 '())))
     identity)
    ; 3