27 lines
1.1 KiB
Plaintext
27 lines
1.1 KiB
Plaintext
;;;; The map operations over a type-variable key, refused at the call site.
|
|
;;;;
|
|
;;;; A generic body is checked once with its type variables abstract, and the
|
|
;;;; map operations are one of the few forms that cannot be answered there:
|
|
;;;; the hash and the equality are emitted as concrete symbols chosen from the
|
|
;;;; concrete key type, and there is none until a copy exists. So they are
|
|
;;;; deferred to the instantiation, the way print and println are.
|
|
;;;;
|
|
;;;; What makes deferring them safe — and different from an unconstrained
|
|
;;;; (+ a b), which stays refused at the definition — is the clause. The
|
|
;;;; signature says {:where (is-hashable $t)}, so a call site that asks for a
|
|
;;;; key type with no usable equality is refused against a requirement the
|
|
;;;; author wrote down, at the call that asked for it. A float is that type:
|
|
;;;; NaN is not equal to itself, and 0.0 and -0.0 are equal while differing
|
|
;;;; bytewise.
|
|
(defn seen? [k $t] bool
|
|
{:where (is-hashable $t)}
|
|
(let [m (map-new t i32)]
|
|
(put m k 1)
|
|
(let [answer (has-key m k)]
|
|
(free m)
|
|
answer)))
|
|
|
|
(defn main [] ()
|
|
(println (seen? 3))
|
|
(println (seen? 1.5)))
|