scheme - 如何在这里反转谓词?

标签 scheme lisp racket predicate function-composition

我有以下过滤程序:

; (2) filter
(define (filter test sequence)
  ; return a list of the elements that pass the predicate test
  (let ((elem (if (null? sequence) nil (car sequence)))
        (rest (if (null? sequence) nil (cdr sequence))))
    (cond ((null? sequence) nil)
          ((test elem) (cons elem (filter test rest)))
          (else (filter test rest)))))

下面是一个使用它返回列表的偶数元素的示例:

(define even? (lambda (x) (= (modulo x 2) 0)))
(define sequence '(1 2 3 4 5 8 9 11 13 14 15 16 17))
(filter even? sequence)
; (2 4 8 14 16)

有没有一种简单的方法来使用 not 测试来反转选择?例如,我认为以下可能有效:

(filter (not even?) sequence)

但它返回一个错误。我当然可以单独定义odd:

(define odd?  (lambda (x) (not (even? x))))

但我尽量不这样做。有没有办法编写 odd 过程而不直接定义它,而是像我上面尝试的那样直接使用 not

最佳答案

有一个complement Common Lisp 中的函数可以满足我的需求。 complement 是一个高阶过程,它接受一个过程作为其参数,并返回一个过程,该过程采用与输入过程相同的参数并执行相同的操作,但返回的真值是相反的。

Racket 也有类似的程序,negate ,并且在 Scheme 中很容易实现:

(define (complement f)
  (lambda xs (not (apply f xs))))
> (filter even? '(1 2 3 4 5))
(2 4)
> (filter (complement even?) '(1 2 3 4 5))
(1 3 5)
> (> 1 2 3 4 5)
#f
> ((complement >) 1 2 3 4 5)
#t

在 Racket 中:

scratch.rkt> (filter even? '(1 2 3 4 5))
'(2 4)
scratch.rkt> (filter (negate even?) '(1 2 3 4 5))
'(1 3 5)
scratch.rkt> (> 1 2 3 4 5)
#f
scratch.rkt> ((negate >) 1 2 3 4 5)
#t

关于scheme - 如何在这里反转谓词?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67796513/

相关文章:

parsing - 在 Racket 中可视化 s-表达

haskell - 如何深入理解SICP中描述的信号流图?

scheme - 如何从 Scheme 中的递归调用正确返回值?

windows - 我无法在 Windows 上设置和配置 Common LISP (SBCL)

namespaces - 在 Racket 中,嵌套函数定义不需要 "local"吗?

scheme - 在racket中实现apply-all功能

if-statement - 解释器,if 语句和 let

stream - Racket 中的可变 zip

lisp - (dolist (element list) ...) 中的 'element' 是什么意思?

lisp - 学习 Lisp 的资源