2024年Clojure调查中分享您的想法!

欢迎!请参阅关于页面以了解更多关于如何使用本网站的信息。

0
Spec

我怀疑是否有一个类似于Prolog中的cut!能够阻止回溯的观念。考虑下面的规格

  (s/def ::nested (s/keys :req-un [::a]))
  (s/def ::a (s/keys :req-un [::b]))
  (s/def ::b (s/keys :req-un [::c]))
  (s/def ::c int?)

  (s/def ::top-level (s/keys :req-un [::x]))
  (s/def ::x int?)

  (s/def ::thing (s/or :nested ::nested :top-level ::top-level))
  (s/valid? ::thing {:x 3}) ; true
  (s/valid? ::thing {:a {:b {:c 3}}}) ;true
  (s/valid? ::thing {:a {:b {:c "not int"}}}) ;false
  (s/explain ::thing {:a {:b {:c "not int"}}}) ;neither toplevel nor nested

这里{:a {:b {:c "not int"}}}显然不符合::nested::toplevel的规范,但一旦检查到::c,它明显是一个未正确格式化的::nested而不是一个未正确格式化的::toplevel

如果这种结构不存在,这是否应该在spec 2中考虑,或者根本不是所希望的吗?

1 个回答

+1

人选
 
最佳答案

Clojure 1.10.1的结果是

user=> (s/explain ::thing {:a {:b {:c "not int"}}})
"not int" - failed: int? in: [:a :b :c] at: [:nested :a :b :c] spec: :user/c
{:a {:b {:c "not int"}}} - failed: (contains? % :x) at: [:top-level] spec: :user/top-level

由于其实现方式并行匹配两者,因此它会提供所有失败的路径。解释信息按照路径长度排序,所以您无意中看到的是“最深”匹配的那个。

我认为不太可能有一个类似于“cut”这样的东西,但是在问题报告中可能会有许多可能的变化。尤其是在扇出(尤其是宽度很大的扇出,这不是这种情况)的特定情况,我认为这是一个更高的优先级,但我们目前没有关于在短期内工作的计划。

...