Closed jcubic closed 3 months ago
It seems one of them is in open PR #43, but this one is much better IMHO.
It would be good to have a version that short-circuits the rest of the tests as soon as one is not identical to the others.
Yes. More generally, a fold with a "stop condition" might be useful.
(define (ordered? fn . args)
(let ((first (car args)))
(fold (lambda (arg result)
(and result (equal? arg first)))
#t
(cdr args))))
(equal? arg first)
should probably be (fn result arg)
I was testing with equal?
now I see that it will not work. You need to have a version of reduce that get a pair of arguments. Like int the linked PR for "Map over n consecutive elements inside a list" but instead of map there should be version of fold so you can exit early. There can be two versions.
I need revisit #43
lol, I was negligent too.
Here's one that should work:
(define (ordered-list? <= list)
(or (null? list)
(let loop ((prev (car list))
(list (cdr list)))
(or (null? list)
(and (<= prev (car list))
(loop (car list)
(cdr list)))))))
(define (ordered? <= . args)
(ordered-list? <= args))
(ordered? <) => #t
(ordered? < 1 2 3 4 5) => #t
(ordered? < 1 2 3 4 4) => #f
(ordered? <= 1 2 3 4 4) => #t
(ordered? string<? "a" "ab" "ba") => #t
(ordered? string<? "a" "ab" "ab") => #f
<=
is perhaps not a good name for the compator in the general case.
Problem
Check if all elements are the same using a predicate.
Solution
I'm not sure if there is already a utility like this in some of SRFI. But there are few solutions on StackOverflow, but they use
equal?
instead of predicate: Scheme: How to check if all elements of a list are identical.I came up with a solution using fold:
Credit: @jcubic
Usage
It can be used to check if strings are sorted (for R5RS implementation where string comparators accept 2 arguments) or check if all elements are equal. You can also check if any sequence is monotonous.