How do I break a Scheme list into args to be passed to a procedure?
-
14-11-2019 - |
Question
I want to use the predefined (max)
function (R5RS) with a list
of numbers, which varies in length. Unfortunately, (max)
accepts input like this:
(max 2 43 5 6)
=> 43
I'm attempting to use it like so:
(define lst '(3 5 53 4 53 54 32))
(max lst)
This produces the following error.
max: expects argument of type <real number>; given (3 5 53 4 53 54 32)
How can I break this list into the individual arguments I need, as I'm passing them to (max)
?
Solution
You might consider using apply
(though be warned, that this may impose limits with respect to the number of elements/arguments are acceptable, depending on your implementation of Scheme):
(apply max '(3 4 2 1 78 2 1))
In general, if the number of elements is not known to be small, it might be safer to do it manually:
(define max* (list)
(if (null? list) (negative-infinity)
(let loop ((list (cdr list)) (best (car list)))
(if (null? list) best (loop (cdr list) (max best (car list)))))))
OTHER TIPS
Using apply basically translates into running (max 3 4 2 1 78 2 1)
but the number of arguments a procedure can be passed is not infinite on some systems. For max
, you can take advantage of its commutativity by using fold:
(fold-left max -inf.0 '(3 4 2 1 78 2 1))
You can write a procedure that compares the first item to the second,
(define (largestele lst)
(if (null? (cdr lst))
(car lst)
(if (> (car lst) (cadr lst))
(largestele (cons (car lst) (cddr lst)))
(largestele (cdr lst)))))