2016-07-04 2 views
1

Предположение: Я в курсе ADT библиотек here. Они классные. Может быть, они могут быть лучше.Что необходимо для реализации ADT в Clojure?

Существует очень интересный пример АТД в Clojure here:

Определим ADT генератор вроде этого:

(defmacro data 
    [adt-name equals-sign & constructors] 
    `(do 
    (defn ~(symbol (str adt-name "?")) [~'obj] 
     (= ~(str adt-name) (adt-name ~'obj))) 
    [email protected](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, но я не могу сказать, что это такое.

Мой вопрос: Что необходимо для внедрения ADT в Clojure?

+2

не ADT без более или менее бесполезны клетчатых типов? Я думаю, вы могли бы представить ADT, как это катаморфизм ... (кстати: шаблон сопоставление/катаморфизм использовать значение то, что я хотел бы рассмотреть без вести - конечно, я не понимаю, Clojure вовсе не так, возможно, это * emited * как-то слишком) – Carsten

ответ

0

Для реализации ADT в clojure вам необходимо быть храбрым и настойчивым.

Для недостающих частей - я не знаю, что вам не хватает, но я знаю, чего я обычно пропускаю.

1) Я хочу, чтобы автоматически получить foldX -функцию для преобразования в кодировку Boehm - естественную складку для этого типа данных.

Это, однако, потребует от вас указать, какие поля должны относиться к объекту того же типа (left и right в вашем случае).

Например, эта функция, написанная для примера типа в 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, как я знаю, и называется «индукция» ,

2) Я хочу видеть предикаты, как isEmpty для всех ветвей. Шутки в сторону. Единственный язык, предоставляющий их, - это Pyret.

3) Для бонусных очков я также хочу иметь возможность derive struct Eq uality, Ord ering, to- and from-string conversion.

∞-1) Чтобы владеть своей душой, вы также можете автоматически генерировать линзы и призмы во всех областях и ветвях соответственно.

∞) Чтобы доказать свою силу, вы также можете генерировать ана-, пара- и апоморфизмы, поскольку foldX - это уже катаморфизм.

Смежные вопросы