I've got the following utility function, which should be self explanatory:
(ns my.utility-belt
"Use this everywhere."
(:use clojure.core.typed))
(ann zipfn (All [c a b ...] [[a b ... b -> c] (Seqable a) * -> (Seqable c)]))
(defn zipfn
"Applies f to the interleaved elements of colls. If 2 colls are given, then f
will recieve 2 arguments, one from each coll. If 3 colls are given, then f
will receive 3 arguments, and so on. Returns a flat sequence of the results of
applying f to its args."
[f & colls]
(map (partial apply f) (partition (count colls) (apply interleave colls))))
(comment
(let [c1 [1 2 3 4 5]
c2 [5 4 3 2 1]]
(assert (= (zipfn * c1 c2)
'(5 8 9 8 5)))))
The annotation I've provided isn't entirely correct, but I have no idea why. Calling (check-ns)
just gives me "Type Error (my/utility_belt.clj:12:51) Bad arguments to polymorphic function in apply in (apply interleave colls)
"
What's the correct type annotation in this case?
The problem is core.typed is having trouble inferring this is the actual type of zipfn
. The quickest way to get around this is to tell core.typed to ignore the definition of zipfn
with :no-check
.
(ann ^:no-check zipfn (All [c a b ...] [[a b ... b -> c] (Seqable a) * -> (Seqable c)]))