The problem is that the `DB` type is _not_ a super-type of
`(Mutable-HashTable Symbol Symbol)`, because mutable data structures
are two way communications channels. If you used an immutable hash,
that's a one-way communication and you would have the expected result.

However, the change you made fixed the problem because it changes the
type that `make-hash` picks to create the hash table. The argument to
`make-hash` has the type `(Listof (Pairof Symbol Symbol))` which _is_
a sub-type of `(Listof (Pairof DBKey (U DB DBValue)))`.

Sam


On Tue, Nov 5, 2019 at 6:39 AM Marc Kaufmann <marc.kaufman...@gmail.com> wrote:
>
> Hi,
>
> in order to put some discipline on my code (and formalize to myself what I'm 
> passing around), I started using typed racket. I have definitely hit my share 
> of gotchas that make me scratch my head, but I kind of start to understand 
> how things work and adding `(ann this-is ThatType)` annotations.
>
> However, I have the following piece of code:
>
> ```
> (: register-study-session! (-> Number Symbol Void))
> (define (register-study-session! sid study-type)
>   (unless (hash-has-key? (db-table 'studies) sid)
>     (hash-set! (db-table 'studies)
>                sid
>                (make-hash (list (cons 'study-type study-type))))))
> ```
>
> then I get the following error:
>
> ```
> exploration.rkt:139:4: Type Checker: Polymorphic function `hash-set!' could 
> not be applied to arguments:
> Argument 1:
>   Expected: (HashTable a b)
>   Given:    DB
> Argument 2:
>   Expected: a
>   Given:    Number
> Argument 3:
>   Expected: b
>   Given:    (Mutable-HashTable Symbol Symbol)
> ```
>
> The DB type is as follows:
>
> ```
> (define-type DBKey (U Symbol Number))
> (define-type DBValue (U Symbol Number Boolean Char))
> (define-type DB (HashTable DBKey (U DB DBValue)))
> ```
>
> However when I annotate this with an (ann ...) around the make-hash, it works:
>
> ```
> (: register-study-session! (-> Number Symbol Void))
> (define (register-study-session! sid study-type)
>   (unless (hash-has-key? (db-table 'studies) sid)
>     (hash-set! (db-table 'studies)
>                sid
>                (ann (make-hash (list (cons 'study-type study-type))) DB)))) 
> ;; ONLY THIS LINE CHANGED
> ```
>
> I don't understand why this leads to it passing, since it said that it 
> thought the DB earlier was a mutable hash of type Symbol to Symbol, which I 
> would have thought is of type DB (which is any hashtable). So why does the 
> type checker complain at first - or maybe why does it pass later?
>
> Cheers,
> Marc
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/6b08ac58-5c85-45ad-9fb7-dd367254e015%40googlegroups.com.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAK%3DHD%2Bah1376yFXvkXTcOevBiAzCbTgQm%3DY9jPiY3jcVujFEmg%40mail.gmail.com.

Reply via email to