Using conj in core.typed

Following code snippet in core.typed

(defn conj-num [coll x]
  (conj coll (byte x)))

(t/cf (t/ann conj-num (t/IFn [(t/ASeq t/Any) t/Any -> (t/ASeq t/Num)])))

(t/cf (reduce conj-num [] (range 10)))

crashes with message

Type Error...
Polymorphic function reduce could not be applied to arguments: 
Polymorphic Variables:  a   c

Domains:    [a c -> (t/U a (Reduced a))] a (t/Option (Seqable c))

Arguments:  [(t/ASeq t/Any) t/Any -> (t/ASeq t/Num)] (t/HVec []) (t/ASeq t/AnyInteger)

Ranges:     a


in: (reduce conj-num [] (range 10))


ExceptionInfo Type Checker: Found 1 error  clojure.core/ex-info (core.clj:4403)

Decreasing fn takes ASeq of Anyanother type argument Anyand returns a sequence of numbers. I expected the result of type checking to be (t/ASeq t/Num), not an error. Any idea what I'm doing wrong here?

Thank.

Edit

Thanks for answers. Now I was able to find out the problem. It is unclear how to interpret the error message given core.typed, but now it really makes sense.

I read the error message above:

Polymorphic Variables:
    a
    c

-> these are function variables reduce. You can determine its signature (or type) with (t/cf reduce). It will show you 3 categories, but the following message indicates which one was selected and why it did not match.

Domains:
    [a c -> (t/U a (Reduced a))] a (t/Option (Seqable c))

core.typed . , .

Ranges:
    a

, a. core.typed b.

( , reduce fn).

Arguments:
    [(t/HVec [t/Num]) t/Any -> (t/HVec [t/Num])] (t/HVec []) (t/ASeq t/Num)

[(t/HVec [t/Num ]) t/Any -> (t/HVec [t/Num])] (t/HVec []) (t/ASeq t/Num)
  --------------  -----    ----------------   --------   ------------
    a               b      (t/U a (Reduced a)    a       (t/Option ...)

,

  • a (t/HVec [t/Num]) - (t/HVec []) - a. , core.typed .
  • (t/U a (Reduced a)) a a. , Reduced a ( , ?), t/U , . a.

, , a , :

;; a is still a vector
(def a [])

;; we give the type (t/HVec [t/Num]) to a. This makes it *more* compatible with our conj-num fn.

(t/cf (t/ann a (t/HVec [t/Num])))

;; core.typed is happy now ;)
(t/cf (reduce conj-num a (range 10)))

a. , conj-num . . . :

(t/cf (t/ann conj-num
            (t/IFn [(t/U (t/HVec [])
                         (t/HVec [t/Num])) t/Num -> (t/HVec [t/Num])])))

;; great. we can now use [] as input.
(t/cf (reduce conj-num [] (range 10)))

, a (t/HVec []), nums (t/HVec [t/Num]), , com-num. . , core.typed , . . , .

+4
2

, a.

:

: [a c → (t/U a ( a))] a (t/Option (Seqable c))

: [(t/ASeq t/Any) t/Any → (t/ASeq t/Num)] (t/HVec []) (t/ASeq t/AnyInteger)

: a

"c" - t/Any, . "a" → "a" (t/Aseq t/Any), (t/U a ( a)) (t/ASeq t/Num). . -num:

[(t/ASeq t/Num) t/Any → (t/ASeq t/Num)]

+1

, conj-num .

.

(ns typed.test
  (:require [clojure.core.typed :as t]))

(t/ann conj-num (t/IFn [(t/ASeq t/Any) t/Any -> (t/ASeq t/Num)]))
(defn conj-num [coll x]
  (conj coll (byte x)))

(reduce conj-num [] (range 10))

conj-num , .

+1

All Articles