Clojure.typed基础知识

时间:2015-02-02 08:59:22

标签: clojure clojure-core.typed

我开始玩看似非常令人印象深刻的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

感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:0)

你的回答现在已经有3年了,所以这可能没什么用,但我在同一时间在一个大型的生产代码库中使用Typed Clojure并且有一些经验。此外,weavejester在Reddit thread中提供的关于该主题的答案非常适合,所以我只是在这里重新总结一下,以便为将来的访问者节省点击其他链接带来的不便。< / p>

一般来说,您的方法在高级别上是正确的,但是您正在遇到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))

问题3

不幸的是,core.typed无法成功推断merge-with(核心函数),当应用于同一类型的两个地图时,将返回相同类型的地图。这是类型检查器的限制。您可以通过重新编写函数来明确合并而不是依赖merge-with

来解决这个问题
(defn v-
  [{x1 :x, y1 :y} {x2 :x, y2 :y}]
  {:x (- x1 x2), :y (- y1 y2)})