diff --git a/collects/lang/private/advanced-funs.rkt b/collects/lang/private/advanced-funs.rkt index 3508b44df8..5c0bc94f5d 100644 --- a/collects/lang/private/advanced-funs.rkt +++ b/collects/lang/private/advanced-funs.rkt @@ -110,18 +110,44 @@ ("Hash Tables" ((advanced-make-hash make-hash) ((listof (list X Y)) -> (hash X Y)) - "to construct a hash table from a list of associations") + "to construct a hash table from a list of mappings that uses equal? for comparisions") + ((advanced-make-hasheq make-hasheq) ((listof (list X Y)) -> (hash X Y)) + "to construct a hash table from a list of mappings that uses eq? for comparisions") + ((advanced-make-hasheqv make-hasheqv) ((listof (list X Y)) -> (hash X Y)) + "to construct a hash table from a list of mappings that uses eqv? for comparisions") (hash-set! ((hash X Y) X Y -> void) - "to update a hash table with a new association") - ((advanced-hash-ref hash-ref) ((hash X Y) X -> Y) - "to extract the value associated with a key from a hash table") + "to update a hash table with a new mapping") + (hash-ref (case-> + ((hash X Y) X -> Y) + ((hash X Y) X Y -> Y) + ((hash X Y) X (-> Y) -> Y)) + "to extract the value associated with a key from a hash table; the three argument case allows a default value or default value computation") + (hash-ref! (case-> + ((hash X Y) X Y -> Y) + ((hash X Y) X (-> Y) -> Y)) + "to extract the value associated with a key from a hash table; if the key does not have an mapping, the third argument is used as the value (or used to compute the value) and is added to the hash table associated with the key") + (hash-update! (case-> + ((hash X Y) X (Y -> Y) -> void) + ((hash X Y) X (Y -> Y) Y -> void) + ((hash X Y) X (Y -> Y) (-> Y) -> void)) + "to compose hash-ref and hash-set! to update an existing mapping; the third argument is used to compute the new mapping value; the fourth argument is used as the third argument to hash-ref") (hash-has-key? ((hash X Y) X -> boolean) "to determine if a key is associated with a value in a hash table") (hash-remove! ((hash X Y) X -> void) - "to remove an association from a hash table") + "to remove an mapping from a hash table") (hash-map ((hash X Y) (X Y -> A) -> (listof A)) - "to construct a new list by applying a function to each association of a hash table") + "to construct a new list by applying a function to each mapping of a hash table") (hash-for-each ((hash X Y) (X Y -> any) -> void) - "to apply a function to each association of a hash table for effect only") + "to apply a function to each mapping of a hash table for effect only") + (hash-count (hash -> integer) + "to determine the number of keys mapped by a hash table") + (hash-copy (hash -> hash) + "to copy a hash table") (hash? (any -> boolean) - "to determine if value is a hash table")))) + "to determine if a value is a hash table") + (hash-equal? (hash -> boolean) + "to determine if a hash table uses equal? for comparisions") + (hash-eq? (hash -> boolean) + "to determine if a hash table uses eq? for comparisions") + (hash-eqv? (hash -> boolean) + "to determine if a hash table uses eqv? for comparisions")))) diff --git a/collects/lang/private/teachprims.rkt b/collects/lang/private/teachprims.rkt index 5acac3b89b..85626a65e4 100644 --- a/collects/lang/private/teachprims.rkt +++ b/collects/lang/private/teachprims.rkt @@ -345,14 +345,18 @@ namespace. (check-last/cycle 'append x) (apply append x))) -(define-teach advanced hash-ref - (lambda (h k) - (hash-ref h k))) - (define-teach advanced make-hash (lambda (a) (make-hash (map (lambda (l) (cons (first l) (second l))) a)))) +(define-teach advanced make-hasheq + (lambda (a) + (make-hasheq (map (lambda (l) (cons (first l) (second l))) a)))) + +(define-teach advanced make-hasheqv + (lambda (a) + (make-hasheqv (map (lambda (l) (cons (first l) (second l))) a)))) + (provide false? beginner-not @@ -383,8 +387,9 @@ namespace. advanced-cons advanced-list* advanced-append - advanced-hash-ref advanced-make-hash + advanced-make-hasheq + advanced-make-hasheqv cyclic-list?) ;; ----------------------------------------------------------------------------- diff --git a/collects/tests/racket/advanced.rktl b/collects/tests/racket/advanced.rktl index d3a9682720..4bea076ae9 100644 --- a/collects/tests/racket/advanced.rktl +++ b/collects/tests/racket/advanced.rktl @@ -208,6 +208,12 @@ (htdp-test #t 'equal~? (equal~? (shared ([x (cons 10 x)]) x) (shared ([x (cons 10.02 x)]) x) 0.1)) (htdp-test #f 'equal~? (equal~? (shared ([x (cons 10 x)]) x) (shared ([x (cons 10.2 x)]) x) 0.1)) +(htdp-test 1 'hash-copy + (local [(define ht (make-hash (list (list 'a 1)))) + (define htp (hash-copy ht))] + (begin (hash-set! htp 'a 2) + (hash-ref ht 'a)))) +(htdp-test 1 'hash-count (hash-count (make-hash (list (list 'a 1))))) (htdp-test 42 'hash-for-each (local [(define x 0) (define (f k v) (set! x 42))] @@ -219,6 +225,18 @@ (hash-map (make-hash (list (list 1 #t) (list 2 #t))) (lambda (k v) (not v)))) (htdp-test 1 'hash-ref (hash-ref (make-hash (list (list 'a 1))) 'a)) +(htdp-test 2 'hash-ref (hash-ref (make-hash (list (list 'a 1))) 'b 2)) +(htdp-test 2 'hash-ref (hash-ref (make-hash (list (list 'a 1))) 'b (lambda () 2))) +(htdp-test 1 'hash-ref! + (local [(define ht (make-hash (list (list 'a 1))))] + (hash-ref! ht 'a 2))) +(htdp-test 2 'hash-ref! + (local [(define ht (make-hash (list (list 'a 1))))] + (hash-ref! ht 'b 2))) +(htdp-test 2 'hash-ref! + (local [(define ht (make-hash (list (list 'a 1))))] + (begin (hash-ref! ht 'b 2) + (hash-ref ht 'b)))) (htdp-test (list #t #f) 'hash-remove! (local [(define ht (make-hash (list (list 'a 1))))] (list (hash-has-key? ht 'a) @@ -228,10 +246,45 @@ (local [(define ht (make-hash (list (list 'a 1))))] (begin (hash-set! ht 'a 2) (hash-ref ht 'a)))) +(htdp-test 2 'hash-update! + (local [(define ht (make-hash (list (list 'a 1))))] + (begin (hash-update! ht 'a add1) + (hash-ref ht 'a)))) +(htdp-test 2 'hash-update! + (local [(define ht (make-hash (list (list 'a 1))))] + (begin (hash-update! ht 'b add1 1) + (hash-ref ht 'b)))) +(htdp-test 2 'hash-update! + (local [(define ht (make-hash (list (list 'a 1))))] + (begin (hash-update! ht 'b add1 (lambda () 1)) + (hash-ref ht 'b)))) (htdp-test #t 'hash? (hash? (make-hash (list (list 'a 1))))) +(htdp-test #t 'hash? + (hash? (make-hasheq (list (list 'a 1))))) +(htdp-test #t 'hash? + (hash? (make-hasheqv (list (list 'a 1))))) (htdp-test #f 'hash? (hash? 1)) +(htdp-test #t 'hash-equal? + (hash-equal? (make-hash (list (list 'a 1))))) +(htdp-test #f 'hash-equal? + (hash-equal? (make-hasheq (list (list 'a 1))))) +(htdp-test #f 'hash-equal? + (hash-equal? (make-hasheqv (list (list 'a 1))))) +(htdp-test #f 'hash-eq? + (hash-eq? (make-hash (list (list 'a 1))))) +(htdp-test #t 'hash-eq? + (hash-eq? (make-hasheq (list (list 'a 1))))) +(htdp-test #f 'hash-eq? + (hash-eq? (make-hasheqv (list (list 'a 1))))) +(htdp-test #f 'hash-eqv? + (hash-eqv? (make-hash (list (list 'a 1))))) +(htdp-test #f 'hash-eqv? + (hash-eqv? (make-hasheq (list (list 'a 1))))) +(htdp-test #t 'hash-eqv? + (hash-eqv? (make-hasheqv (list (list 'a 1))))) + ;; Simulate set! in the repl (module my-advanced-module (lib "htdp-advanced.rkt" "lang")