Clojure.typed基础知识

Mát*_*ari 11 clojure clojure-core.typed

我开始玩看似非常令人印象深刻的clojure.typed库,但是在我遇到问题之后不久,即使尝试将它应用于简单的函数.有没有人有图书馆的经验?

问题1

(typed/ann square [Double -> Double])
(defn square "Square of"
  [num]
  (* num  num))
Run Code Online (Sandbox Code Playgroud)

类型错误(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))
Run Code Online (Sandbox Code Playgroud)

类型错误(clojure_study/ideas/swarm/vector_algebra.clj:28:3)应用于多态函数的错误参数:(应用合并 - +向量)

问题3

(typed/ann v- [CartesianVector CartesianVector -> CartesianVector])
(defn v- "Diff vector of vectors"
  [v1 v2]
  (merge-with - v1 v2))
Run Code Online (Sandbox Code Playgroud)

类型错误(clojure_study/ideas/swarm/vector_algebra.clj:33:3)多态函数merge-with无法应用于参数:Polymorphic Variables:k v

感谢您提供的任何帮助.

Ven*_*ius 1

你的答案已经有 3 年历史了,所以这可能没有太大帮助,但我大约在同一时间在一个大型生产代码库中使用 Typed Clojure,并且有一些经验。另外,weavejester 在您的Reddit 主题中提供的答案非常准确,因此我将在这里重新总结它们,以免未来的访问者必须单击另一个链接而带来不便。

总的来说,你的方法在高层次上是正确的,但你遇到了一些core.typed根本不知道(也许仍然不知道)如何明智行事的领域。

这是发生的事情:

问题1

这可能应该被视为代表 的错误core.typed,因为有一个函数签名支持Double作为返回类型。您可以通过使用clojure.lang.Numberclojure.core.typed/Num来避免这种情况,两者都包含LongDouble

问题2

这只是一个语法错误 - 这不是您指定映射到core.typed. 您应该使用HMap

(t/defalias CartesianVector
  (t/HMap :mandatory {:x t/Num, :y t/Num} :complete? true))
Run Code Online (Sandbox Code Playgroud)

问题3

不幸的是,core.typed无法成功推断merge-with(核心函数)应用于相同类型的两个映射时将返回相同类型的映射。这是类型检查器的限制。您可以通过重写函数以显式合并而不是依赖来解决此问题merge-with

(defn v-
  [{x1 :x, y1 :y} {x2 :x, y2 :y}]
  {:x (- x1 x2), :y (- y1 y2)})
Run Code Online (Sandbox Code Playgroud)