1

I know how to write this in an recursive way.

(define (removed2 lst)
  (cond
       [(empty? lst) empty]
       [(not (member? (first lst) (rest lst)))
        (cons (first lst) (removed2 (rest lst)))]
       [else (removed2 (rest lst))]))

so (removed2 (list 1 1 1 2 2 2 3 3 3 3 3 3)) gives (list 1 2 3)

However, how do you rewrite it only using abstract functions (filter, foldr, map, and build-list)?

I tried to use filter but it just doesn't work.

uselpa
  • 18,732
  • 2
  • 34
  • 52
6609081
  • 111
  • 1
  • 2

2 Answers2

3

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.

Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • yes, but Racket docs http://docs.racket-lang.org/reference/pairs.html#(def._((lib._racket/private/list..rkt)._foldr)) says `foldl` runs in constant space, and `foldr` in O(n) space. :) – Will Ness Jan 24 '14 at 07:32
2

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)))
uselpa
  • 18,732
  • 2
  • 34
  • 52