在 Clojure 中实现 ADT 需要什么?

What is required to implement an ADT in Clojure?

假设:我知道 ADT libraries here。他们很酷。也许他们可以做得更好。

Clojure 中有一个非常有趣的 ADT 示例 here:

我们这样定义一个 ADT 生成器:

(defmacro data
  [adt-name equals-sign & constructors]
  `(do
     (defn ~(symbol (str adt-name "?")) [~'obj]
       (= ~(str adt-name) (adt-name ~'obj)))
     ~@(for [[type-name & fields]
             (filter (partial not= '(|))
                     (partition-by (partial = '|) constructors))]
         (apply (partial emit-constructor adt-name type-name)
                 fields))))

给定 Haskell 示例:

data Tree a = Empty
        | Leaf a
        | Node Tree Tree

然后我们写Clojure

(data Tree = Empty | Leaf value | Node left right)

这很酷。

现在我觉得与 Haskell 等价物的匹配缺少一些东西,但我不能完全确定它是什么。

我的问题是:在 Clojure 中实现 ADT 需要什么?

要在 clojure 中实现 ADT,您需要勇敢和坚持。

对于遗漏的部分——我不知道你遗漏了什么,但我知道我通常遗漏了什么。

1) 我想自动获取一些 foldX 函数来执行到 Boehm 编码的转换 - 这种数据类型的自然折叠。

但是,这将要求您让用户指定哪些字段必须引用相同类型的对象(在您的情况下为 leftright)。

例如,为您在 haskell 中键入的示例编写的函数(上帝保佑懒惰!)将如下所示:

foldTree :: a -> (v -> a) -> (a -> a -> a) -> Tree v -> a
foldTree empty value node = go 
  where
    go tree =
      case tree of
        Empty    -> empty
        Value v  -> value v
        Node l r -> node (go l) (go r)

据我所知,这是在 Coq 中完成的,并称为 "induction"。

2) 我希望看到所有分支的谓词,如 isEmpty。严重地。唯一提供它们的语言是 Pyret。

3) 对于奖励积分,我还希望有一些能力 derive 结构 Eq 质量,Ord ering,to- and from-string conversion.

∞-1)为了拥有我的灵魂,你还可以相应地自动生成透镜和棱镜到所有领域和分支中。

∞)为了证明自己的实力,你还可以生成ana-,para-和同构,因为foldX已经是一个同构。