[racket] (check-equal? hash1 hash2) fails

From: Greg Hendershott (greghendershott at gmail.com)
Date: Sat Aug 17 09:57:36 EDT 2013

Well you could write your own predicate -- what you expected
`hash-equal?` to be. Let's call it `hash-equivalent?`:

#lang racket

(define (hash-equivalent? a b)
  (for/and ([(k v) (in-hash a)])
    (and (hash-has-key? b k)
         (equal? (hash-ref b k) v))))

;; Testing
(require rackunit)
(define assocs '([a 0] [b 1]))
(define m (make-hash assocs))
(define i (make-immutable-hash assocs))
(check-true (hash-equivalent? m m))
(check-true (hash-equivalent? i i))
(check-true (hash-equivalent? m i))
(check-false (hash-equivalent? (make-hash '([a 0])) (make-hash '([a 1]))))
(check-false (equal? m i))

But actually, these days I would probably instead write a
`dict-equivalent?`, since it will work with all the hash variants,
association lists, and so on:

(define (dict-equivalent? a b)
  (for/and ([(k v) (in-dict a)])
    (and (dict-has-key? b k)
         (equal? (dict-ref b k) v))))

;; Testing
(check-true (dict-equivalent? m m))
(check-true (dict-equivalent? i i))
(check-true (dict-equivalent? m i))
(check-false (dict-equivalent? (make-hash '([a 0])) (make-hash '([a 1]))))

p.s. There is no `dict-equal?`, so I suppose you could name it that
instead. Not sure if that would be less confusing, or more so.


On Sat, Aug 17, 2013 at 9:27 AM, J G Cho <gcho at fundingmatters.com> wrote:
> You were right on.
>
> So I converted one of the mutable and it worked:
> (make-immutable-hash  (hash->list mutable-hash))
>
> Is there a better way?
>
>
> On Sat, Aug 17, 2013 at 9:18 AM, Robby Findler <robby at eecs.northwestern.edu>
> wrote:
>>
>> Those are equal if they are both mutable or both immutable. Probably one
>> is mutable and the other isn't (this, unfortunately, doesn't show up in the
>> print outs). It is quite confusing, I agree.
>>
>> > (equal? #hash((6 . 1) (4 . 1) (3 . 2) (2 . 2)) #hash((2 . 2) (3 . 2) (4
>> > . 1) (6 . 1)))
>> #t
>>
>> Robby
>>
>>
>>
>> On Sat, Aug 17, 2013 at 8:13 AM, J G Cho <gcho at fundingmatters.com> wrote:
>>>
>>> FAILURE
>>> actual:     #hash((6 . 1) (4 . 1) (3 . 2) (2 . 2))
>>> expected:   #hash((2 . 2) (3 . 2) (4 . 1) (6 . 1))
>>> name:       check-equal?
>>>
>>> I tried alternative like
>>> (check-true (hash-equal? hash1 hash2))
>>>
>>>  but it turns out hash-equal? is not what I expected it to be.
>>>
>>> Other than writing a custom comparison, is there a handy way to compare 2
>>> #hash?
>>>
>>> jGc
>>>
>>> ____________________
>>>   Racket Users list:
>>>   http://lists.racket-lang.org/users
>>>
>>
>
>
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users
>

Posted on the users mailing list.