ฉันจะตอบคำถามนี้ทีละน้อย เริ่มต้นด้วยเพรดิเคต=สมมูล เพรดิเคต=ใช้เพื่อตรวจสอบว่าตัวเลขสองตัวเท่ากันหรือไม่ หากคุณจัดหาสิ่งอื่นใดนอกจากตัวเลขจะทำให้เกิดข้อผิดพลาด:
(= 2 3) => #f
(= 2.5 2.5) => #t
(= '() '()) => error
เพรดิเคตeq?ใช้เพื่อตรวจสอบว่าพารามิเตอร์สองตัวแสดงถึงวัตถุเดียวกันในหน่วยความจำหรือไม่ ตัวอย่างเช่น:
(define x '(2 3))
(define y '(2 3))
(eq? x y) => #f
(define y x)
(eq? x y) => #t
อย่างไรก็ตามโปรดทราบว่ามีรายการว่างเพียงรายการเดียว'()ในหน่วยความจำ (จริงๆแล้วรายการว่างไม่มีอยู่ในหน่วยความจำ แต่ตัวชี้ไปยังตำแหน่งหน่วยความจำ0ถือเป็นรายการว่าง) ดังนั้นเมื่อเปรียบเทียบรายการว่างeq?จะกลับมาเสมอ#t(เนื่องจากเป็นตัวแทนของวัตถุเดียวกันในหน่วยความจำ):
(define x '())
(define y '())
(eq? x y) => #t
ตอนนี้ขึ้นอยู่กับการนำไปใช้eq?หรืออาจไม่คืน#tค่าดั้งเดิมเช่นตัวเลขสตริง ฯลฯ ตัวอย่างเช่น:
(eq? 2 2) => depends upon the implementation
(eq? "a" "a") => depends upon the implementation
นี่คือจุดที่เพรดิเคตเข้าeqv?มาในรูปภาพ ค่าeqv?นี้เหมือนกับเพรดิเคตทุกประการeq?ยกเว้นว่าจะกลับมา#tเป็นค่าดั้งเดิมที่เหมือนกันเสมอ ตัวอย่างเช่น:
(eqv? 2 2) => #t
(eqv? "a" "a") => depends upon the implementation
ดังนั้นจึงeqv?เป็น superset eq?และสำหรับกรณีส่วนใหญ่คุณควรใช้eqv?แทนeq?แทน
ในที่สุดเราก็มาถึงเพequal?รดิเคต เพรดิเคตequal?จะเหมือนกับเพรดิเคตทุกประการeqv?ยกเว้นว่าสามารถใช้เพื่อทดสอบว่าทั้งสองรายการเวกเตอร์ ฯลฯ มีองค์ประกอบที่สอดคล้องกันซึ่งตรงตามเพรดิเคตeqv?หรือไม่ ตัวอย่างเช่น:
(define x '(2 3))
(define y '(2 3))
(equal? x y) => #t
(eqv? x y) => #f
โดยทั่วไป:
- ใช้เพรดิเคต
=เมื่อคุณต้องการทดสอบว่าตัวเลขสองตัวเท่ากันหรือไม่
- ใช้เพรดิเคต
eqv?เมื่อคุณต้องการทดสอบว่าค่าที่ไม่ใช่ตัวเลขสองค่าเท่ากันหรือไม่
- ใช้เพรดิเคต
equal?เมื่อคุณต้องการทดสอบว่าสองรายการเวกเตอร์และอื่น ๆ เท่ากันหรือไม่
- อย่าใช้เพรดิเคต
eq?เว้นแต่คุณจะรู้แน่ชัดว่ากำลังทำอะไรอยู่
eqv?ซึ่งหมายถึงสิ่งที่แตกต่างจากeq?หรือequal?