我开始玩看似非常令人印象深刻的clojure.typed库,但是在我遇到问题后不久,即使尝试将它应用于简单的函数。有没有人有图书馆的经验?
问题1
(typed/ann square [Double -> Double])
(defn square "Square of"
[num]
(* num num))
类型错误(clojure_study / ideas / swarm / vector_algebra.clj:15:3)返回静态方法的类型clojure.lang.Numbers / multiply是java.lang.Long,期望java.lang.Double。
问题2
(typed/defalias CartesianVector '{:x Double :y Double})
(typed/ann v+ [CartesianVector * -> CartesianVector])
(defn v+ "Sum vector of vectors"
[& vectors]
(apply merge-with + vectors))
类型错误(clojure_study / ideas / swarm / vector_algebra.clj:28:3)应用中的多态函数的错误参数 in :(应用与+向量合并)
问题3
(typed/ann v- [CartesianVector CartesianVector -> CartesianVector])
(defn v- "Diff vector of vectors"
[v1 v2]
(merge-with - v1 v2))
类型错误(clojure_study / ideas / swarm / vector_algebra.clj:33:3)多态函数merge-with无法应用于参数: 多态变量: ķ v
感谢您提供的任何帮助。
答案 0 :(得分:0)
你的回答现在已经有3年了,所以这可能没什么用,但我在同一时间在一个大型的生产代码库中使用Typed Clojure并且有一些经验。此外,weavejester在Reddit thread中提供的关于该主题的答案非常适合,所以我只是在这里重新总结一下,以便为将来的访问者节省点击其他链接带来的不便。< / p>
一般来说,您的方法在高级别上是正确的,但是您正在遇到core.typed
根本没有(可能仍然没有)知道如何巧妙行事的领域。
这是发生了什么:
问题1
这应该被视为代表core.typed
的错误,因为有一个函数签名支持Double
作为返回类型。您可以使用clojure.lang.Number
或clojure.core.typed/Num
来避免这种情况,两者都包含Long
和Double
。
问题2
这只是一个语法错误 - 这不是指定地图到core.typed
的方式。您应该使用HMap
代替:
(t/defalias CartesianVector
(t/HMap :mandatory {:x t/Num, :y t/Num} :complete? true))
问题3
不幸的是,core.typed
无法成功推断merge-with
(核心函数),当应用于同一类型的两个地图时,将返回相同类型的地图。这是类型检查器的限制。您可以通过重新编写函数来明确合并而不是依赖merge-with
:
(defn v-
[{x1 :x, y1 :y} {x2 :x, y2 :y}]
{:x (- x1 x2), :y (- y1 y2)})