I know how to write this in an recursive way.
(define (removed2 lst)
(cond
[(empty? lst) empty]
[(not (member? (first lst) (rest lst)))
It's possible to use foldr
for this, the trick is knowing what to write in the lambda
:
(define (removed lst)
(foldr (lambda (e a)
(if (not (member? e a))
(cons e a)
a))
'()
lst))
Also check if your interpreter has a built-in function, for instance in Racket you can use remove-duplicates
.
FILTER
Just for kicks, a version with filter
:
(define (make-unique-filter)
(let ((seen '()))
(lambda (e)
(if (member e seen)
#f
(begin
(set! seen (cons e seen))
#t)))))
(define (removed2 lst)
(filter (make-unique-filter) lst))
then
(removed2 (list 1 1 1 2 2 2 3 3 3 3 3 3))
=> '(1 2 3)
(removed2 (list 1 2 3 1 2 3 1 2 3 1 2 3))
=> '(1 2 3)
FOLD
But of course, fold is the way to go. However, it is generally preferable to user a left fold (at least in Racket, see here), but the result has to be reversed:
(define (removed2 lst)
(reverse
(foldl
(lambda (e a)
(if (not (member e a))
(cons e a)
a))
'()
lst)))
or in pure Scheme:
(define (removed2 lst)
(reverse
(fold-left
(lambda (a e)
(if (not (member e a))
(cons e a)
a))
'()
lst)))