I assumed it was something to do with mutability, but I don't understand
what you mean when you say there is a two-way channel. The reference in
typed racket (
https://docs.racket-lang.org/ts-reference/type-ref.html#%28form._%28%28lib._typed-racket%2Fbase-env%2Fbase-types..rkt%29._.Hash.Table%29%29)
says this:

```

(HashTable
<https://docs.racket-lang.org/ts-reference/type-ref.html#%28form._%28%28lib._typed-racket%2Fbase-env%2Fbase-types..rkt%29._.Hash.Table%29%29>
 k v)

is the type of a mutable or immutable hash table
<https://docs.racket-lang.org/reference/hashtables.html#%28tech._hash._table%29>
with key type k and value type v.
Example:

> (make-hash
<https://docs.racket-lang.org/reference/hashtables.html#%28def._%28%28quote._~23~25kernel%29._make-hash%29%29>
 '((a . 1) (b . 2)))

- : (HashTable Symbol Integer) [more precisely: (Mutable-HashTable Symbol
Integer)]

'#hash((a . 1) (b . 2))

```

That suggests to me that HashTable includes both Mutatable-HashTable and
Immutable-HashTable. The example given even states that the HashTable
Symbol Integer is more precisely of Mutable-HashTable Symbol Integer type -
does that *not* mean that (Mutable-HashTable Symbol Integer) is a subtype
of (HashTable Symbol Integer) in the reference example?

I now tried to redefine DB as Mutable-HashTable to avoid this issue, but
that doesn't work either. It still doesn't accept `(make-hash (list (cons
'study-type study-type)))` as something of type DB. How is
(Mutable-HashTable Symbol Symbol) not a subtype of DB, which is
(Mutable-HashTable DBKey (U DB DBValue)), and DBKey is (U Symbol ... ;other
stuff) and same for DBValue?

You wrote that make-hash is of type `(Listof (Pairof Symbol Symbol))`. Is
there a way to expand and print the type of something in terms of primitive
types (well, or maybe step through one layer of abstraction) so that I
could play around with some toy examples to get a sense of what types are
returned? I am clearly confused by what type `make-hash` returns and what
`hash-ref` expects.

Cheers,
Marc


On Tue, Nov 5, 2019 at 3:22 PM Sam Tobin-Hochstadt <[email protected]>
wrote:

> 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 <[email protected]>
> 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 [email protected].
> > 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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAD7_NO4-cDE_3AHZ%3Dv9ieC%2BjYEvgXgWcQG_TGA0DqbmX%3DBH%3DYQ%40mail.gmail.com.

Reply via email to