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

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

0
规范

我在想是否有类似于 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”类型的东西,但在问题报告中还有很多可能的变化。特别是在扇出(尤其是广泛扇出,这并不是这种情形)的情况下,我认为这是一个更高优先级的问题,但我们目前没有计划在短期内着手解决这个问题。

...