方案 - 如何在' map / filter'中使用函数?如果它有多个参数?

时间:2016-11-07 17:32:40

标签: filter scheme racket currying map-function

我一直在尝试创建一个子集?,成员?和交集函数使用预定义的过滤函数和map函数的一些变体(ormap,andmap)。

"会员?"函数应该检查元素是否是列表的成员:

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

它正在使用一个名为" same-elem的函数?"看起来像这样:

(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)))))

"子集?"检查一组中的元素是否属于另一组的一部分:

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

'''函数应该返回两组的交集:

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

我正在使用咖喱'函数是因为我试图按照此stackoverflow线程中的解决方案:Scheme/Racket filter/map multiple arguments尝试将第二个参数传递给我的被调用函数。它虽然不起作用。

每当我调用这些函数中的任何一个时,它都会输出一个错误,表示它希望我的成员中的ormap调用中有一个列表?功能,但有一个元素。奇怪的是我的成员?功能工作得很好,直到几分钟前...我甚至没有触及任何东西!

我是编程方面的新手,我对Scheme完全不熟悉。我知道如果map / filter中的被调用函数只有一个参数,如何使用map / filter函数...但是如果我有多个参数,我该如何处理呢?请帮忙。

编辑:我在下面选择的解决方案DOESN&T使用咖喱。但它确实有效,如果你删除咖喱功能并改为写一个匿名函数。

像这样:

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

1 个答案:

答案 0 :(得分:1)

您的方法是正确的,您只需要小心参数的顺序 - 例如,member?如果您打算咖喱它,应该收到一个集合作为第一个参数,因为andmap会将单个元素传递给生成的lambda表单。另请注意,使用的高阶过程需要列出作为参数,而不是内置set数据类型的实际。这就是我的意思:

; 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)))

他们按预期工作:

(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)