flan/test/programs/generic-map-reject.flan

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)))