add section to guide on structure equality
svn: r14049
This commit is contained in:
parent
9a900d5100
commit
0c36eb9ae6
|
@ -188,6 +188,72 @@ can use an opaque structure to encapsulate data, and clients of the
|
||||||
library cannot manipulate the data in the structure except as allowed
|
library cannot manipulate the data in the structure except as allowed
|
||||||
by the library.
|
by the library.
|
||||||
|
|
||||||
|
@; ------------------------------------------------------------
|
||||||
|
@section[#:tag "struct-equal"]{Stucture Comparisons}
|
||||||
|
|
||||||
|
A generic @scheme[equal?] comparison automatically recurs on the
|
||||||
|
fields of a transparent structure type, but @scheme[equal?] defaults
|
||||||
|
to mere instance identity for opaque structure types:
|
||||||
|
|
||||||
|
@def+int[
|
||||||
|
#:eval posn-eval
|
||||||
|
(define-struct glass (width height) #:transparent)
|
||||||
|
(equal? (make-glass 1 2) (make-glass 1 2))
|
||||||
|
]
|
||||||
|
@def+int[
|
||||||
|
#:eval posn-eval
|
||||||
|
(define-struct lead (width height))
|
||||||
|
(define slab (make-lead 1 2))
|
||||||
|
(equal? slab slab)
|
||||||
|
(equal? slab (make-lead 1 2))
|
||||||
|
]
|
||||||
|
|
||||||
|
To support instances comparisons via @scheme[equal?] without making
|
||||||
|
the structure type transparent, you can use the @scheme[#:property]
|
||||||
|
keyword, @scheme[prop:equal+hash], and then a list of three functions:
|
||||||
|
|
||||||
|
@def+int[
|
||||||
|
#:eval posn-eval
|
||||||
|
(define-struct lead (width height)
|
||||||
|
#:property
|
||||||
|
prop:equal+hash
|
||||||
|
(list (lambda (a b equal?-recur)
|
||||||
|
(code:comment #, @t{compare @scheme[a] and @scheme[b]})
|
||||||
|
(and (equal?-recur (lead-width a) (lead-width b))
|
||||||
|
(equal?-recur (lead-height a) (lead-height b))))
|
||||||
|
(lambda (a hash-recur)
|
||||||
|
(code:comment #, @t{compute primary hash code of @scheme[a]})
|
||||||
|
(+ (hash-recur (lead-width a))
|
||||||
|
(* 3 (hash-recur (lead-height a)))))
|
||||||
|
(lambda (a hash2-recur)
|
||||||
|
(code:comment #, @t{compute secondary hash code of @scheme[a]})
|
||||||
|
(+ (hash2-recur (lead-width a))
|
||||||
|
(hash2-recur (lead-height a))))))
|
||||||
|
(equal? (make-lead 1 2) (make-lead 1 2))
|
||||||
|
]
|
||||||
|
|
||||||
|
The first function in the list implements the @scheme[equal?] test on
|
||||||
|
two @scheme[lead]s; the third argument to the function is used instead
|
||||||
|
of @scheme[equal?] for recursive equality testing, so that data cycles
|
||||||
|
can be handled correctly. The other two functions compute primary and
|
||||||
|
secondary hash codes for use with @tech{hash tables}:
|
||||||
|
|
||||||
|
@interaction[
|
||||||
|
#:eval posn-eval
|
||||||
|
(define h (make-hash))
|
||||||
|
(hash-set! h (make-lead 1 2) 3)
|
||||||
|
(hash-ref h (make-lead 1 2))
|
||||||
|
(hash-ref h (make-lead 2 1))
|
||||||
|
]
|
||||||
|
|
||||||
|
The first function provided with @scheme[prop:equal+hash] is not
|
||||||
|
required to recursively compare the fields of the structure. For
|
||||||
|
example, a structure type representing a set might implement equality
|
||||||
|
by checking that the members of the set are the same, independent of
|
||||||
|
the order of elements in the internal representation. Just take care
|
||||||
|
that the hash functions produce the same value for any two structure
|
||||||
|
types that are supposed to be equivalent.
|
||||||
|
|
||||||
@; ------------------------------------------------------------
|
@; ------------------------------------------------------------
|
||||||
@section{Structure Type Generativity}
|
@section{Structure Type Generativity}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
@title[#:tag "hash-tables"]{Hash Tables}
|
@title[#:tag "hash-tables"]{Hash Tables}
|
||||||
|
|
||||||
A @defterm{hash table} implements a mapping from keys to values, where
|
A @deftech{hash table} implements a mapping from keys to values, where
|
||||||
both keys and values can be arbitrary Scheme values, and access and
|
both keys and values can be arbitrary Scheme values, and access and
|
||||||
update to the table are normally constant-time operations. Keys are
|
update to the table are normally constant-time operations. Keys are
|
||||||
compared using @scheme[equal?] or @scheme[eq?], depending on whether
|
compared using @scheme[equal?] or @scheme[eq?], depending on whether
|
||||||
|
|
Loading…
Reference in New Issue
Block a user