Эксклюзив ИЛИ в Схеме - PullRequest
6 голосов
/ 19 декабря 2009

Что такое эксклюзив или функции в схеме? Я пробовал xor и ^, но оба дают мне несвязанную ошибку локальной переменной.

Гугл ничего не нашел.

Ответы [ 9 ]

9 голосов
/ 19 декабря 2009

Насколько я могу судить по R6RS (последнее определение схемы), предопределенных исключительных операций или операций нет. Тем не менее, xor эквивалентно not equals для логических значений, поэтому очень легко определить самостоятельно, если для него нет встроенной функции.

Предполагается, что аргументы ограничены логическими значениями схемы #f и #t,

(define (xor a b)
  (not (boolean=? a b)))

сделает работу.

9 голосов
/ 19 декабря 2009

Я предлагаю вам использовать (not (equal? foo bar)), если не равно работает. Обратите внимание, что для вашей ситуации могут быть более быстрые компараторы, такие как eq?

7 голосов
/ 19 декабря 2009

Если вы имеете в виду побитовый xor двух целых чисел, то каждая схема имеет свое собственное имя (если оно есть), поскольку оно не соответствует ни одному стандарту. Например, PLT имеет эти побитовые функции , включая bitwise-xor.

(э-э, если вы говорите о логических значениях, то да, not & or это ...)

6 голосов
/ 29 декабря 2009

Вид ответа другого стиля:

(define xor
  (lambda (a b)
    (cond
      (a (not b))
      (else b))))   
2 голосов
/ 15 августа 2011

Чтение SRFI-1 пролило новый свет на мой ответ. Забудьте об эффективности и простоте или даже о тестировании! Эта красота делает все это:

(define (xor . args)
  (odd? (count (lambda (x) (eqv? x #t)) args)))

Или, если вы предпочитаете:

(define (true? x) (eqv? x #t))
(define (xor . args) (odd? (count true? args)))
0 голосов
/ 02 сентября 2012

Я недавно пересмотрел свой код, потому что мне нужен был 'xor' в схеме и обнаружил, что он недостаточно хорош ...

Во-первых, мое более раннее определение «правда»? сделал предположение, что аргументы были проверены в логической операции. Поэтому я меняю:

(define (true? x) (eqv? #t))

... для:

(define (true? x) (not (eqv? x #f)))

... что больше похоже на «истинное» определение «правда»? Однако, поскольку 'xor возвращает #t, если его аргументы имеют' нечетное? Количество «истинных» аргументов, тестирование на четное количество ложных случаев эквивалентно. Итак, вот мой пересмотренный 'xor:

(define (xor . args)
  (even? (count (lambda (x) (eqv? x #f)) args)))
0 голосов
/ 05 июня 2012
(define (xor a b)
  (and 
   (not (and a b))
   (or a b)))
0 голосов
/ 19 января 2012
> (define (xor a b)(not (equal? (and a #t)(and b #t))))
> (xor 'hello 'world)
$9 = #f
> (xor #f #f)
$10 = #f
> (xor (> 1 100)(< 1 100))
$11 = #t
0 голосов
/ 08 июня 2011

Поскольку xor может использоваться с любым количеством аргументов, единственным требованием является то, чтобы количество истинных вхождений было нечетным. Это можно определить примерно так:

(define (true? x) (eqv? x #t))

(define (xor . args)
  (odd? (length (filter true? args))))

Проверка аргументов не требуется, поскольку любое количество аргументов (включая ни одного) вернет правильный ответ.

Однако, у этой простой реализации есть проблемы с эффективностью: длина и фильтр пересекают список дважды; поэтому я подумал, что смогу удалить и ту, и другую бесполезную процедуру предиката "true?".

Значение нечетное? receive - это значение аккумулятора (aka acc), когда args не имеет оставшихся истинно оценивающих членов. Если существуют члены с истинной оценкой, повторите с acc + 1, а остальные аргументы начинаются со следующего значения true или оцените как false, что приведет к тому, что acc будет возвращен с последним счетом.

(define (xor . args)
  (odd? (let count ([args (memv #t args)]
                    [acc 0])
          (if args
              (count (memv #t (cdr args))
                     (+ acc 1))
              acc))))
...