代码之家  ›  专栏  ›  技术社区  ›  djhaskin987

如何最好地与clojure抽象集成?

  •  3
  • djhaskin987  · 技术社区  · 11 年前

    我正在clojure中实现一个有序集,在这里我根据元素的秩来检索元素。这意味着我可以在对数时间内检索第4个元素(根据集合的排序)、第3个或第7个。

    为了使我的新数据结构与clojure的常用方法(或“抽象”)集成,例如 conj , get , nth ,等等,哪种方法更好:

    1. 实际执行 联合 例如,在我的数据类型的协议中,或者
    2. 实施Rich Hickey的 clojure.lang.IPersistentSet 或者类似的界面。

    第一个似乎更容易,但也更容易混淆函数的语义。第二个问题似乎是我正在实现一个从未打算成为公共API一部分的接口,而与该接口(协议)相关的实际方法却有着令人困惑的不同。例如,为了实现 联合 对于我的集合,我必须实现 cons 方法 clojure.lang.持久设置 ,它有一个不同的名称。关于这一切是如何运作的,似乎几乎没有文献记载,这给实现这一排名集带来了巨大挑战。

    我应该选择哪一个?我应该实施我自己的方法还是 clojure.lang 界面如果我应该做后者,那么哪里有一些好的文档可以指导我完成整个过程?

    编辑 :我想明确一点,我正在尝试创建一个集合,通过指定元素的 等级 (例如,“给我第五个元素,set先生。”)。据我所知,clojure中还不存在这样的集合。

    1 回复  |  直到 11 年前
        1
  •  4
  •   Michał Marczyk    11 年前

    首先,我刚刚发布了一个名为 avl.clj 它实现了持久的排序映射和集合,并支持标准的Clojure API(它们是内置排序集合的替代品),以及瞬态和对数时间秩查询(通过 clojure.core/nth ) 1. 。同时支持Clojure和ClojureScript;Clojure方面的性能大部分与我初步基准测试中的内置变体不相上下。如果你想尝试一下,请点击上面的链接。任何经验报告都将不胜感激!

    至于实际的问题:恐怕Clojure的内部接口没有太多的文档,但实现它们仍然是使自定义数据结构与内置程序相适应的唯一方法。 core.rrb-vector (我已经编写并维护了它)采用了这种方法,其他实现各种数据结构的Contrib库也是如此。这也是我对avl.clj所做的,以及 sorted.clj (基本上是向后移植到Clojure的基于红黑树的排序集合的ClojureScript端口)。所有这些库,以及Clojure自己的库 gvec.clj 实现基元存储向量的文件 clojure.core/vector-of ,可以作为所涉及内容的示例。(尽管我不得不说,这里和那里很容易错过一个方法…)

    ClojureScript中的情况要简单得多,其中所有核心协议都定义在 core.cljs ,所以您可以查看列表并选择与您的数据结构相关的列表。希望有一天Clojure一方也会如此。


    1. 按级别删除 (disj my-set (nth my-set 123)) 目前。如果在性能方面有足够的差异,我可能会在以后提供一个直接的实现。(如果有,我一定会写一封来检查。)