Как мне передать (не f) как f? - PullRequest
0 голосов
/ 25 ноября 2018

У меня есть функция фильтра, которая принимает предикат как нечетный?и обрабатывает список.Вот код

(define (manual-filter f? lst)
(cond
[(empty? lst) empty]
[(f? (first lst)) (cons (first lst) (manual-filter f? (rest lst)))]
[else (manual-filter f? (rest lst))]))

Как я могу передать (не (f?)) Функцию?

Ответы [ 2 ]

0 голосов
/ 25 ноября 2018

Решение

Напишите функцию, которая возвращает лямбда-выражение с применением not к применению вашей функции предиката для любого аргумента.

(define (my-not predicate-func)
  (lambda (x) (not (predicate-func x))))

(my-not f?) возвращает затем функцию, которая является инвертированной функцией предиката f?.(Таким образом, compose не требуется ... - ну my-not вручную compose -из функции not с f? (предикат-функцией) в ее теле определения функции).

Я назвал это my-not, чтобы не перезаписывать уже существующую функцию not в Racket, которая конвертирует логические значения, таким образом, возвращает логическое значение.(my-not принимает функцию и возвращает функцию - Function -> Function или lambda -> lambda :).)

my-not также можно назвать invert.

Приложение

Таким образом, вы можете дать (my-not f?) вашей функции manual-filter вместо f?:

(manual-filter (my-not f?) lst)

Попробуйте

Вы также можете проверить:

(even? 3) ;; #f
(even? 4) ;; #t

((my-not even?) 3) ;; #t
((my-not even?) 4) ;; #f

;; so `(my-not even?)` behaves exactly like `odd?` - the inverse of `even?`
(odd? 3) ;; #t
(odd? 4) ;; #f
0 голосов
/ 25 ноября 2018

функция not имеет подпись Any -> Boolean.И это по существу:

(define (not x)
  (if (eq? x #f) #t #f))

То, что вы ищете, - это функция, которая инвертирует вывод в другую заданную функцию.(Или, в основном, функция подписи: (Any -> Boolean) -> (Any -> Boolean)

Как и предположил @Sylwester, самый простой способ сделать это с помощью compose. Вы можете определить это как:

(define (invert f)
  (compose not f))

Теперь вы можете, скажем, определить even? как:

(define even? (invert odd?))

Вы также можете определить invert без использования compose. Я дам вам шаблон, а остальное оставлю в качестве упражнения:

;; Invert the results of a predicate
;; (Any -> Boolean) -> (Any -> Boolean)
(define (invert f)
  (lambda (x)
    (cond
      [(f x) ...]
      [else ...])))

(Обратите внимание, что в ракетке есть сокращение для таких функций:

 (define ((invert f) x)
   (cond
     [(f x) ...]
     [else ...]))
...