请在 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)。第二种情况是 OK 的,因为它经过了我自己实现的 IUnifyTerms。可能我错了,但我认为如果没有在 core.logic 本身中进行更改,我就不能使其工作。

0

评论由:dnolen

我们以前支持双向统一,但这就需要实现大量协议。最近我一直在思考,提供强制协议可能很有用,类似于 ICoerceToSequential。

0

评论由:mikera

我认为,如果自定义数据结构在 core.logic 中要成为第一类公民,就需要能够在某种方式下支持双向统一。

我了解如何使用 ICoerceToSequential 来实现这一点,所以这可能是一个好的解决方案。我们在 core.matrix 中做了类似的事情(处理不同后端矩阵之间的强制转换)。

0

评论由:dnolen

自定义数据结构已经是第一类了。是否应该允许使用 core Clojure 接口/协议/类型来过载自定义类型的统一,完全是另一回事。

很抱歉造成混淆。我不太明白你为什么想让序列工作,从你的例子来看,你已经有了一种适当的表达式类型,统一到序列有什么好处吗?

0

评论由:mikera

如果你有“类似序列”的数据结构,这些数据结构不是严格序列,但在概念上等效于序列,我认为这可能很重要。我的自定义Expression类型就是一个例子,也因为互操作性,像java.util.ArrayList这样的类型也会出现在我的脑海中。

不过,我现在已经切换回使用常规列表,所以这个问题对我来说不是障碍。但也许仍然值得考虑。

这种类型统一的一些优势似乎包括:
a) 符号表示 - 你可以使用常规Clojure列表和矢量来与类似序列的东西进行统一
b) 效率 - 当不需要时避免创建新的自定义对象(虽然成本可能过于微不足道,以至于大多数情况下不必在意……)

当然,你可能会决定避开这些复杂化,选择更简单、更纯粹的方案,这也是可以接受的。但似乎有点可惜,有这么多可扩展的协议,而不能完全将这些功能扩展到自定义类型……

0
...