2
votes

I have been trying to create a subset?,member? and intersection function by using the predefined filter function and some variations of the map function (ormap, andmap).

The "member?" function is supposed to check if a element is a member of a list:

(define member?
 (lambda (e s)
  (ormap (curry same-elem? e) s)))

It is using a function called "same-elem?" that looks like this:

(define same-elem?
 (lambda (e1 e2)
  (cond ((and (set? e1) (set? e2)) (same-set? e1 e2))
        ((and (number? e1) (number? e2)) (= e1 e2))
        (else (equal? e1 e2)))))

The "subset?" checks if the elements in one set are part of another set:

(define subset?
 (lambda (s2 s1)
  (andmap (curry member? s2) s1)))

The 'intersection' function is supposed to return the intersection of two sets:

(define intersection
 (lambda (s2 s1)
  (filter (curry member? s2) s1)))

The reason I am using the 'curry' function is because I tried to follow the solution in this stackoverflow thread:Scheme/Racket filter/map multiple arguments in an attempt to pass a second argument into my called function. It doesn't work though.

Whenever I call any of these functions it outputs an error that says it expected a list in my ormap call in my member? function but got an element. The weird part is that my member? function worked fine until like a couple of minutes ago... I haven't even touched anything!

I am kind of a newbie in programming and I am completely new to Scheme. I know how to use a map/filter function if the called function in map/filter only has one argument... but how do I handle this if I have multiple arguments? Please help.

EDIT: The solution I picked below DOESN'T work with curry. It does work however if you remove the curry function and write a anonymous function instead.

Like this:

(define member?
 (lambda (e s)
  (ormap (lambda (x)
           (same-elem? e x)) s)))
1
The procedure same-set? is undefined, did you mean set-equal?Óscar López
same-set? isnt undefined. I just forgot to add it to the post.Schytheron

1 Answers

2
votes

Your approach is correct, you just have to be careful with the order of the parameters - for instance, member? should receive a set as its first parameter if you intend to curry it, because andmap will pass single elements to the resulting lambda form. Also, notice that the higher-order procedures in use expect lists as parameters, not actual sets of the built-in set data type. This is what I mean:

; tests if `e` is a member of `s`
(define member?
  (lambda (s e)
    (ormap (curry same-elem? e) s)))

; tests if `s1` is a subset of `s2`
(define subset?
  (lambda (s1 s2)
    (andmap (curry member? s2) s1)))

; finds the intersection of `s1` and `s2`    
(define intersection
  (lambda (s1 s2)
    (filter (curry member? s1) s2)))

They work as expected:

(member? '(a b c d e) 'c)
=> #t
(subset? '(c d) '(a b c d e))
=> #t
(intersection '(c d b a) '(a x y b))
=> '(a b)