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 <sa...@cs.indiana.edu>
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 <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/CAD7_NO4-cDE_3AHZ%3Dv9ieC%2BjYEvgXgWcQG_TGA0DqbmX%3DBH%3DYQ%40mail.gmail.com.

Reply via email to