В чем разница между eq, eql, equal и equalp в Common Lisp?
В чем разница между eq
, eql
, equal
и equalp
в Common Lisp? Я понимаю, что некоторые из них проверяют типы, некоторые из них проверяют все типы, но что это такое? Когда лучше использовать, чем другие?
- В чем разница между этим и Activity.this
- Как использовать двойные или одиночные скобки, круглые скобки, фигурные скобки
- Преобразование двоичной строки в байтовый массив
- Почему должно быть место после « в Bash?
- Лучший способ разделить строку на строки
- Почему операторы присваивания возвращают значение?
- Ошибка 1064 в CREATE TABLE ... TYPE = MYISAM
- Почему я не должен смешивать вкладки и пробелы?
От Common Lisp: Предикаты равенства
(eq xy)
истинно тогда и только тогда, когдаx
иy
– один и тот же идентичный объект.Предикат
eql
истинен, если его аргументы равныeq
, или если они являются номерами одного и того же типа с одинаковым значением или являются символьными объектами, которые представляют один и тот же символ.
equal
предикат является истинным, если его аргументы являются структурно подобными (изоморфными) объектами. Грубое эмпирическое правило состоит в том, что два объекта равны тогда и только тогда, когда их печатные представления одинаковы.Два объекта равны
equalp
если они равны; если они являются символами и удовлетворяют char-equal, что игнорирует алфавитный случай и некоторые другие атрибуты символов; если они являются числами и имеют одинаковое числовое значение, даже если они имеют разные типы; или если у них есть компоненты, всеequalp
.
Вот несколько примеров из той же страницы, с которой я связан выше:
(eq 'a 'b) is false. (eq 'a 'a) is true. (eq 3 3) might be true or false, depending on the implementation. (eq 3 3.0) is false. (eq 3.0 3.0) might be true or false, depending on the implementation. (eq #c(3 -4) #c(3 -4)) might be true or false, depending on the implementation. (eq #c(3 -4.0) #c(3 -4)) is false. (eq (cons 'a 'b) (cons 'a 'c)) is false. (eq (cons 'a 'b) (cons 'a 'b)) is false. (eq '(a . b) '(a . b)) might be true or false. (progn (setq x (cons 'a 'b)) (eq xx)) is true. (progn (setq x '(a . b)) (eq xx)) is true. (eq #\A #\A) might be true or false, depending on the implementation. (eq "Foo" "Foo") might be true or false. (eq "Foo" (copy-seq "Foo")) is false. (eq "FOO" "foo") is false. (eql 'a 'b) is false. (eql 'a 'a) is true. (eql 3 3) is true. (eql 3 3.0) is false. (eql 3.0 3.0) is true. (eql #c(3 -4) #c(3 -4)) is true. (eql #c(3 -4.0) #c(3 -4)) is false. (eql (cons 'a 'b) (cons 'a 'c)) is false. (eql (cons 'a 'b) (cons 'a 'b)) is false. (eql '(a . b) '(a . b)) might be true or false. (progn (setq x (cons 'a 'b)) (eql xx)) is true. (progn (setq x '(a . b)) (eql xx)) is true. (eql #\A #\A) is true. (eql "Foo" "Foo") might be true or false. (eql "Foo" (copy-seq "Foo")) is false. (eql "FOO" "foo") is false. (equal 'a 'b) is false. (equal 'a 'a) is true. (equal 3 3) is true. (equal 3 3.0) is false. (equal 3.0 3.0) is true. (equal #c(3 -4) #c(3 -4)) is true. (equal #c(3 -4.0) #c(3 -4)) is false. (equal (cons 'a 'b) (cons 'a 'c)) is false. (equal (cons 'a 'b) (cons 'a 'b)) is true. (equal '(a . b) '(a . b)) is true. (progn (setq x (cons 'a 'b)) (equal xx)) is true. (progn (setq x '(a . b)) (equal xx)) is true. (equal #\A #\A) is true. (equal "Foo" "Foo") is true. (equal "Foo" (copy-seq "Foo")) is true. (equal "FOO" "foo") is false. (equalp 'a 'b) is false. (equalp 'a 'a) is true. (equalp 3 3) is true. (equalp 3 3.0) is true. (equalp 3.0 3.0) is true. (equalp #c(3 -4) #c(3 -4)) is true. (equalp #c(3 -4.0) #c(3 -4)) is true. (equalp (cons 'a 'b) (cons 'a 'c)) is false. (equalp (cons 'a 'b) (cons 'a 'b)) is true. (equalp '(a . b) '(a . b)) is true. (progn (setq x (cons 'a 'b)) (equalp xx)) is true. (progn (setq x '(a . b)) (equalp xx)) is true. (equalp #\A #\A) is true. (equalp "Foo" "Foo") is true. (equalp "Foo" (copy-seq "Foo")) is true. (equalp "FOO" "foo") is true.
Еще несколько примечаний:
-
Большинство функций CL неявно используют EQL, если не указан тест
-
См. Также STRING-EQUAL, = и TREE-EQUAL
-
В основе EQ обычно входит сравнение указателей
И приблизительное руководство:
Для сравнения с ... Используйте ... Объекты / Структуры EQ NIL EQ (но функция NULL более кратка и, вероятно, дешевле) T EQ (или просто значение, но тогда вам не нужен тип) Точные числа EQL Поплавки = Символы EQL или CHAR-EQUAL Списки, Conses, Sequences EQ (если вы хотите точно такой же объект) EQUAL (если вам просто нравятся элементы) Строки EQUAL (с учетом регистра), EQUALP (без учета регистра) STRING-EQUAL (если вы бросаете символы в микс) Деревья (списки списков) TREE-EQUAL (с соответствующим аргументом TEST)
Заметим, что для эффективности обычно EQ >> EQL >> EQUAL >> EQUALP.
Отсюда и слайды моего учителя
eq, чтобы увидеть, являются ли его аргументы (представленные одним и тем же блоком памяти компьютера) одним и тем же символом.
Например:
(eq ‘A’ B) NIL
(эквалайзер ОЗУ RAM) T
(eq (cons ‘a’ b) (cons a ‘b’)); Это связано с тем, что для обоих минусов выполняются разные вызовы, поэтому им, очевидно, будут выделены разные куски памяти
eql первых тестов, чтобы убедиться, что его аргументы удовлетворяют EQ, если нет, он пытается увидеть, являются ли они номерами одного типа и значений.
Например:
(4,0 4) NIL
(eql 4 4) T
Теперь обратите внимание на разницу :
(eq 4.0 4.0) NIL; Зависит от платформы, как описано в первом (принятом) ответе
(eql 4.0 4.0) T; тип и значение аргументов одинаковы
В некоторых реализациях (eq 4.0 4.0) может возвращаться true, потому что в стандарте не указано, должна ли реализация содержать только одну копию чисел и символов в памяти, например, с символами). Как правило , не использовать eq на числа и символы , если вы действительно не знаете, что делаете.
equal – это «более простая» функция сравнения. Как правило, вы можете думать об этом как о том, являются ли два объекта одинаковыми (структурно схожими или изоморфными). Вероятно, это оператор, который вы хотите использовать для общего равенства. Он ведет себя как eql для чисел, символов и символов, но для списков (conses) и строк он сообщает, если их элементы
Например:
(равным 4 4) T
(равно (+ 2 2) 4) T
Теперь обратите внимание на разницу
(eql (cons ‘a’ b) (cons ‘a’ b)) NIL
(равный (минус «a» b) (cons «a» b)) T; равное обычно верно для вещей, которые печатают одинаковые
equalp похоже на равный, просто более продвинутый. Сравнение чисел нечувствительно к типу. Сравнение символов и строк нечувствительно к регистру.
Например:
(equalp (cons ‘a’ b) (cons ‘a’ b)) T; такой же, как равный
Теперь обратите внимание на разницу
равный (4,0) NIL
equalp (4,0,0) T; Поскольку equalp относится к типу чисел нечувствительно