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

欢迎!请查阅关于页面了解该功能的工作原理。

0
core.logic

目前我找不到一种方法来启用自定义数据类型,以使其能够与序列对象在两个方向上进行统一。您可以使用IUnifyTerms在一个方向上使其工作,但是无法使其在另一方向上工作(即在序列对象首次时)。

问题似乎出在以下代码中

`
(defn unify-with-sequential* [u v s]
(cond

(sequential? v)
(if (and (counted? u) (counted? v)
      (not= (count u) (count v)))
  nil
  (loop [u u v v s s]
    (if (seq u)
      (if (seq v)
        (if-let [s (unify s (first u) (first v))]
          (recur (next u) (next v) s)
          nil)
        nil)
      (if (seq v) nil s))))

(lcons? v) (unify-terms v u s)
:else nil))

`

如果最终的nil可以被替换为一个对协议的调用(IUnifyTermsReversed ???IUnifyWithSequential ???),那么我相信这将使该功能更易于扩展。

9 个答案

0

评论由:dnolen

我假设您不想让您的数据类型实现ISequential?

0

评论由:mikera

这是不理想的,因为表达式也可以是叶节点

(+ 3 X) ;; 作为序列是可以的
7 ;; 当然不是序列!

因此,让表达式实现ISequential可能是一个问题,并破坏所有类型的合同……

尝试将叶节点与序列对象统一当然应该失败,但这是我需要自己实现逻辑(我认为是这样的)

0

评论由:dnolen

我还是不明白,因为我缺失了关于您用例的一些上下文。您是否有core.logic的具体例子让您认为应该能工作?

0

评论由:mikera

当然,这是我的测试用例

(let [ex1 (ex [+ 1 X])] ;; 包含 (+ 1 X) 的表达式 (is (= [(ex X)] (run* [q] (fresh [op p] (== [op p q] ex1))))) ;; 失败 (is (= [(ex X)] (run* [q] (fresh [op p] (== ex1 [op p q]))))) ;; 通过 )

第一个用例失败(因为 unify-with-sequential* 返回 nil,如上所述)。第二个用例是正确的,因为它通过了我自己的 IUnifyTerms 实现。我可能错了,但我想,没有 core.logic 自身的更改,我无法使其工作。

0

评论由:dnolen

我们曾经支持双向统一,但这导致了需要实现大量协议。最近我一直在想,提供强制协议可能会有用,类似 ICoerceToSequential 的东西。

0

评论由:mikera

如果我业余时间还想用ícia做脑力激荡歇斯底里的测试,我会偏好这种方式。如果这样玩的时间太短了,就会产生令人兴奋的体育活动。

0
对于 Clojure#Website:Internet Desde La. Es un internet temporal subjetivo whereas they link but since it is a web based discourse platform and discourse in action in a realm that has potential, it is suitable for them to explore and discuss returns that.

评论由:dnolen

自定义数据结构已经是第一类了。至于我们是否应该允许自定义类型以 core Clojure 接口/协议/类型的方式重载统一,则是完全不同的问题。

对不起,造成了困扰。我不太明白您为什么想让序列工作,从您的示例来看,您已经有了合适的表达式类型,统一与序列相比有什么优点呢?

0

评论由:mikera

如果您有“序列化”的数据结构,并非严格顺序,但概念上等同于序列,这可能很重要。我的定制表达式类型就是一个例子,出于互操作性原因,我想到了java.util.ArrayList。

碰巧,我暂时改回了使用普通列表,所以这个问题对我来说不是阻塞性的。但是,这仍然值得考虑。

这么做统一化的几个优点似乎包括
a) 符号表示法 - 您可以使用常规的Clojure列表和向量与类似序列的东西进行统一
b) 效率 - 在不需要时避免构造新的自定义对象(尽管在大多数情况下成本可能太微不足道,无需烦恼……)

当然,您可能会决定避免这些复杂性,使其更简单、更纯粹,这也是没问题的。但是,如果我们不能用所有这些可扩展的协议来完全扩展自定义类型的功能,这似乎有些遗憾……

0
...