试图在Dr. Racket中实现删除*?

时间:2016-09-16 03:33:05

标签: scheme lisp racket

(define (removeAll list-a list-b)
  (if (empty? list-b)
    list-a
    (apply
      (removeAll((remove (first list-b) list-a) (rest list-b)))
    )
  )
)

(removeAll '(a b b c c d) '(a c a))

在这种情况下,

预期输出为'(b b d)

我可以使用删除但我不能使用删除*本身。目前我收到此错误: application: not a procedure; expected a procedure that can be applied to arguments given: '(b b c c d) arguments...:

1 个答案:

答案 0 :(得分:3)

如果您在DrRacket中执行程序,您将获得错误消息,并清楚地证明其原因:

enter image description here

你看到问题出在里面:

((remove (first list-b) list-a) (rest list-b)))

原因是在方案中你不能像其他语言一样自由地使用括号:(+ 2 (+ 3 4))不等于(+ 2 ((+ 3 4))):第一个表达式被评估为9,第二个给出错误,因为((+ 3 4))以这种方式解释:

  1. 评估内部表单(表达式)(+ 3 4),即将操作+应用于参数3和4,生成7。
  2. 由于(+ 3 4)位于另一组括号内,因此获取结果并尝试将(7)评估为表单。但7 是一个运算符(“不是一个过程”,如错误消息所示),因此会引发错误。
  3. 在您的情况下,remove的结果是一个列表,这不能用作运算符。

    如果以这种方式删除双括号:

    (removeAll (remove (first list-b) list-a) (rest list-b))
    

    您将删除第一个错误,并且您将看到另一个错误,特别是:

    apply: arity mismatch;
     the expected number of arguments does not match the given number
      expected: at least 2
      given: 1
      arguments.:
    

    这是一个可能的解决方案:

    (define (removeAll list-a list-b)
      (if (empty? list-b)
          list-a
          (removeAll (filter (lambda (x) (not (eq? (first list-b) x))) list-a) (rest list-b))))
    

    函数filter删除所有不满足谓词的元素。