【问题标题】:What does this clojure.core.typed type error mean?这个 clojure.core.typed 类型错误是什么意思?
【发布时间】:2014-02-11 00:59:17
【问题描述】:

我想让clojure.core.typed 类型检查通过,但我遇到了一个我不理解的类型错误。

我的问题是:

  • 以下错误是什么意思?
  • 我该如何解决?

这是我的代码(我意识到这是不正确的):

(ns clj.util.map
  (:require [clojure.core.typed :as t]))

(t/ann map-vals
       (All [k v1 v2]
            (Fn [ (Fn [(t/Option v1) -> (t/Option v2)])
                  (t/Option (t/Map k v1)) ->
                  (t/Option (t/Map k v2)) ])))

(defn map-vals
  ;; FIXME: Incorrect code
  "Apply a function to each of the values in a map, returning the updated map."
  [f hm]
  (t/doseq> [k :- Any (keys hm)]
            (assoc hm k (f (get hm k)))))

这是lein typed check clj.util.map的输出:

Initializing core.typed ...
"Elapsed time: 6697.604 msecs"
core.typed initialized.
Start collecting clj.util.map
Finished collecting clj.util.map
Collected 1 namespaces in 6851.111 msecs
Start checking clj.util.map
Checked clj.util.map in 968.041 msecs
Checked 1 namespaces (approx. 21 lines) in 7823.552 msecs
Type Error (clj.util.map:14:23) Polymorphic function clojure.core/keys could not be applied to arguments:
Polymorphic Variables:
    k

Domains:
    (t/Map k Any)

Arguments:
    (t/Option (t/Map k v1))

Ranges:
    (t/Seq k) :object {:path [Keys], :id 0}

in: (clojure.core/keys hm)
in: (clojure.core/seq (clojure.core/keys hm))


Type Checker: Found 1 error
Found errors
Subprocess failed

【问题讨论】:

    标签: types clojure clojure-core.typed


    【解决方案1】:

    错误的第一部分告诉您这与对clojure.core/keys 的调用有关。您可以使用(cf keys) 查找类型。

    (All [k] [(Map k Any) -> (Seq k) :object {:id 0 :path [Keys]}])

    错误基本上是总结这种多态类型与提供给函数的实际类型并列。

    Polymorphic Variables 列出了All 绑定器中的所有变量及其类型界限。 k 是唯一的变量,它基本上没有边界,所以会显示k

    Domains 按顺序列出所有参数类型(-> 的左侧)。如果Fn指定了多个参数,则每个参数列表将按顺序显示。

    Arguments 向您显示实际上传递给函数的类型。 14:23的代码大概是这个调用(keys hm),所以显示第一个参数的类型:(t/Option (t/Map k v1))

    Ranges 按顺序列出所有返回类型(-> 的右侧)。

    有时存在Expected 类型,它必须与Range 匹配,就像所有Arguments 必须与Domain 匹配一样。

    我们可以通过比较DomainsArguments 来诊断这个错误。 Arguments 的列表必须适合Domains 的一个列表,并且匹配是自上而下尝试的。如果没有DomainsArguments 匹配,我们会收到这样的类型错误;精确定位约束算法失败的位置通常过于复杂,因此会向用户提供大量信息。

    在这种情况下,我们尝试将参数 (t/Option (t/Map k v1)) 拟合到域 (t/Map k Any) 下,但失败了。这是因为参数(t/Option (t/Map k v1))(U nil (t/Map k v1)) 相同,而nil 不适合域(t/Map k Any)

    有几种方法可以解决此问题。您基本上需要确保keys 没有通过nil。这是一种选择:

    (keys (or hm {}))

    【讨论】:

    • 很好的解释;完全有道理。感谢您,感谢您在 clojure.core.typed 上的出色工作!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-29
    相关资源
    最近更新 更多