usage of conj in core.typed
中的以下代码段
1 2 3 4 5 6 | (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))) |
失败,显示消息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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) |
化简fn接受一个
谢谢。
编辑
感谢您的回复。我现在能够找出问题所在。目前尚不清楚如何解释
我现在如下读取错误消息
1 2 3 | Polymorphic Variables: a c |
->这是
1 2 | Domains: [a c -> (t/U a (Reduced a))] a (t/Option (Seqable c)) |
1 2 | Ranges: a |
所以我们必须专注于
以下消息是关于匹配的实际类型的(我们的参数的类型与
1 2 | Arguments: [(t/HVec [t/Num]) t/Any -> (t/HVec [t/Num])] (t/HVec []) (t/ASeq t/Num) |
我们手工匹配
1 2 3 | [(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 []) 也必须是(t/HVec []) ,因为第二次出现a 。由于不能同时使用两者,因此core.typed正确会失败。 -
类型
(t/U a (Reduced a)) 匹配任何a 或简化的a 。我不明白Reduced a 的含义(也许与传感器有关?),但是t/U 只是意味着它可以匹配或匹配。因此,在我们的情况下,它只是a 本身。
此示例中缺少的是确保类型a必须在两侧都匹配,例如:
1 2 3 4 5 6 7 8 9 | ;; 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))) |
破解
1 2 3 4 5 6 | (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))) |
此签名现在有效,因为第一个参数
命令的顺序意味着未检查功能
我建议改为在文件中检查。
1 2 3 4 5 6 7 8 | (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)) |
这很可能是因为类型检查引擎无法匹配类型变量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(Reduced a))是(t / ASeq t /数字)。不匹配。我建议将conj-num类型更改为:
[(t / ASeq t / Num)t /任意->(t / ASeq t / Num)]