Замена Clojure для ADT Haskell и сопоставление с образцом?

Всякий раз, когда в Haskell нам нужен какой-то вариантный тип данных, мы будем использовать ADT в сочетании с сопоставлением с образцом. Что разработчики Clojure используют для таких случаев?


person NeoKlojurian    schedule 22.08.2010    source источник


Ответы (5)


Что ж, на самом деле есть несколько библиотек сопоставления с образцом, написанных для Clojure. Макросы Clojure делают это возможным. Matchure — один из последних. Есть даже кое-что для ADT в вкладе.

Не обращая внимания на это, самое близкое к АТД Haskell в ядре Clojure — это новые записи и типы данных в Clojure 1.2. Но если вам не нужны преимущества использования записи или типа данных, вы обычно будете использовать карту. Clojure — это динамический язык, поэтому вы не получите проверку статического типа, если используете запись и тому подобное.

Clojure имеет «деструктурирование», которое напоминает сопоставление с образцом и часто используется в идиоматическом Clojure. См. это и это. Первый - это ваш покорный ответ здесь, на SO. ;п

person Rayne    schedule 22.08.2010

Это немного зависит от того, что вы пытаетесь сделать. Но если предположить, что в общем случае требуется полиморфное поведение на основе типа данных, протоколы часто являются хорошим подходом:

(defprotocol Fooable
  (foo [x]))

(defrecord AType [avalue]
  Fooable 
    (foo [x]
      (println (str "A value: " (:avalue x)))))

(defrecord BType [avalue]
  Fooable 
    (foo [x]
      (println (str "B value: " (:bvalue x)))))

(foo (AType. "AAAAAA"))    
=> A value: AAAAAA

(foo (BType. "BBBBBB"))    
=> B value: BBBBBB

В этом контексте протокол фактически определяет набор операций, которые вы хотите использовать в своем АТД, а записи определяют возможные значения АТД, а также полиморфное поведение функций протокола.

person mikera    schedule 14.06.2012

Посмотрите на библиотеку matchure — она должна быть скоро будет включено в clojure-contrib

person Alex Ott    schedule 22.08.2010

Мне очень нравится yap как библиотека сопоставления с образцом.

Наличие как ключевых слов, так и символов делает реализацию варианта довольно простой поверх библиотеки сопоставления с образцом.

person Nicolas Oury    schedule 22.08.2010

Возможно использование мультиметодов и макросов.

Один пример можно найти ниже.

Как они выглядят в Clojure?

Синтаксис, который будет использовать эта реализация ADT, будет выглядеть следующим образом:

(defadt Tree
 (Empty)
 (Leaf value)
 (Node left right))

Этот синтаксис невероятно похож на код Haskell. Мы также увидим, что мы можем определить функцию глубины, описанную выше, следующим образом:

(defmulti depth adt-type)
(defmethod depth Empty [_] 0)
(defmethod depth Leaf [_] 1)
(defmethod depth Node [node]
  (+ 1 (max (depth (node :left)) (depth (node :right)))))
(defmethod depth :default [_] 0)

Источник: http://gizmo385.github.io/clojure/programming/2015/08/11/adts-in-clojure.html

person Erik Kaplun    schedule 02.08.2019