首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在core.typed中clojure.core.type/cf何时计算和推断类型?

在core.typed中clojure.core.type/cf何时计算和推断类型?
EN

Stack Overflow用户
提问于 2015-06-17 10:49:17
回答 1查看 45关注 0票数 1

我不太理解行为或clojure.core.typed/cf,如下所述。

我假设cf用于推断表单的类型。

代码语言:javascript
复制
(t/cf (+ 1 2)) => Long

现在,这一切都失败了

代码语言:javascript
复制
(t/cf (/ 1 0)) => Error

这表明在类型检查之前对sexpr进行了评估。我原以为是Long

当我定义自定义函数时:

代码语言:javascript
复制
(t/ann my-fn [t/Any -> t/Num])
(defn my-fn [x]
  (assert (number? x))
  (println "CALLED")
  x)

我可以在同一个表达式中再次使用它,它失败了,这表明fn确实被调用了。

代码语言:javascript
复制
(t/cf (/ 1 (my-fn 0)) => Error, because it evaluates my-fn. no type inference here??

然而,下面这些对我来说是没有意义的。

代码语言:javascript
复制
(t/cf (range)) => (t/ASeq t/AnyInteger)

为什么在这种情况下函数范围没有计算,如果它确实计算了表达式,下面的示例应该返回相同的类型:

代码语言:javascript
复制
(t/cf (->> (range 2) vec)) =>  (t/AVec (t/U Short Byte Integer BigInteger Long BigInt))
(t/cf [0 1]) =>  [(t/HVec [(t/Val 0) (t/Val 1)]) {:then tt, :else ff}]

但他们会返回不同的类型。

我的直觉是,它与常量有关,即当我输入包含t/Val's的表单时,core.typed会自动地对它进行评估。然而,这并不能解释为什么对于某些函数,它不对其进行评估。2(range 2)中肯定是一个常量,那么为什么行为上会有这种差异。

如果表单是在类型检查之前计算的,那么下面的操作应该具有相同的行为

代码语言:javascript
复制
(t/cf (map inc (range 10))))
(t/cf (map #(inc %) (range 10))))

core.typed确实看到了不同之处。第二个示例失败了,因为匿名fn默认接收到一个t/Any,您不能在它上调用inc。因此,这意味着core.typed必须对表单进行一些分析,加上它还会对表单进行评估。我觉得有点困惑,我承认,也许有人能启发我。

编辑:一个简短的摘要

为什么在某些情况下,以下关系似乎是正确的,而不是所有的情况?

代码语言:javascript
复制
(t/cf form) <=> (let [x form] (t/cf x))
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-19 05:13:29

core.typed执行完全静态类型检查。

cf的编译pipleline是read -> analyze -> type check -> eval

如果存在静态类型错误,则认为这是致命的。

否则,将执行评估。

(cf (/ 1 0))抛出一个运行时错误,因为(/ 1 0)是一个类型良好的表达式。

需要评估的原因与分析Clojure代码的实用性有关--如果分析代码而不对代码进行评估,就会发生奇怪的事情。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30889367

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档