I’m learning accumulation and foldr but something in my code is wrong. I’d like compare elements in all the list but foldr use only first and second element. Here is my code:
(define accum?
(lambda (list1 pre?)
(foldr (lambda (x y)
(if (pre? (car list1) (cadr list1)) #t #f))
#f
list1)))
(accum? '(1 2 3 4) <) --> #t
(accum? '(3 2 3 4) <) --> #f
(accum? '(1 2 5 4) <) --> #t (should be #f)
(accum? '(5 7 2 3) <) --> #t (should be #f)
Do you have any idea where is a mistake? By the way, it is better to use only (pre? (car list1) (cadr list1)) without if –> (if <…> #t #f)?
This problem can be solved a lot easier with
apply, using the fact that the comparison operators receive a variable number of arguments:UPDATE
For this problem in particular,
foldris not the right tool for the job (although it’s not impossible, as you’ve demonstrated) – there isn’t a value to be “accumulated” while the list is being traversed, the list is either ordered or not for the given predicate.From the comments, I understand that the
pre?procedure can be an arbitrarylambdathat receives exactly two parameters.A possible solution would be to create al list of all pairs of consecutive elements, and check if the predicate holds true for all of them. Notice that the last element won’t have a corresponding pair, so we need to exclude it from the list of pairs. For that, I’ll define a special
zipprocedure that, given two input lists, takes care of creating a list of pairs taking into account the fact that the lists can be of different lengths:Now putting all together, we can solve the original problem like this:
Bear in mind that it won’t work for empty lists, but it’s trivial to add a special case for this. Now the comparison can be made with arbitrary
lambdas: