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 , . . , .