Odpowiem na to pytanie stopniowo. Zacznijmy od =
predykatu równoważności. =
Orzecznik służy do sprawdzania, czy dwie liczby są równe. Jeśli podasz cokolwiek innego niż liczbę, spowoduje to błąd:
(= 2 3) => #f
(= 2.5 2.5) => #t
(= '() '()) => error
eq?
Orzecznik służy do sprawdzenia, czy jej dwa parametry respresent tego samego obiektu w pamięci. Na przykład:
(define x '(2 3))
(define y '(2 3))
(eq? x y) => #f
(define y x)
(eq? x y) => #t
Zauważ jednak, że '()
w pamięci jest tylko jedna pusta lista (w rzeczywistości pusta lista nie istnieje w pamięci, ale wskaźnik do lokalizacji pamięci 0
jest uważany za pustą listę). Stąd przy porównywaniu pustych list eq?
zawsze zwróci #t
(ponieważ reprezentują ten sam obiekt w pamięci):
(define x '())
(define y '())
(eq? x y) => #t
Teraz, w zależności od implementacji, eq?
może zwracać lub nie zwracać #t
wartości pierwotnych, takich jak liczby, łańcuchy itp. Na przykład:
(eq? 2 2) => depends upon the implementation
(eq? "a" "a") => depends upon the implementation
Tutaj pojawia się eqv?
predykat. eqv?
Jest dokładnie taka sama jak eq?
orzecznika, chyba że będzie to zawsze powrócić #t
do tych samych wartościach pierwotnych. Na przykład:
(eqv? 2 2) => #t
(eqv? "a" "a") => depends upon the implementation
W związku z tym eqv?
jest nadzbiorem eq?
i w większości przypadków należy używać eqv?
zamiast eq?
.
Wreszcie dochodzimy do equal?
orzeczenia. equal?
Orzecznikiem jest dokładnie taka sama jak eqv?
orzecznika, oprócz tego, że może być on również używany do badania, czy dwie listy, wektory, itd. Mają odpowiednie elementy, które spełniają eqv?
predykat. Na przykład:
(define x '(2 3))
(define y '(2 3))
(equal? x y) => #t
(eqv? x y) => #f
Ogólnie:
- Użyj
=
predykatu, jeśli chcesz sprawdzić, czy dwie liczby są równoważne.
- Użyj
eqv?
predykatu, jeśli chcesz sprawdzić, czy dwie wartości nienumeryczne są równoważne.
- Użyj
equal?
predykatu, jeśli chcesz sprawdzić, czy dwie listy, wektory itp. Są równoważne.
- Nie używaj
eq?
predykatu, chyba że dokładnie wiesz, co robisz.
eqv?
, co oznacza coś innego niżeq?
lubequal?