Подтвердить что ты не робот

Функции соответствия шаблонов в Clojure?

Я использовал erlang в прошлом, и у него есть некоторые действительно полезные вещи, такие как функции сопоставления рисунков или "функции защиты". Пример из документов erlang:

fact(N) when N>0 -> 
    N * fact(N-1); 
fact(0) ->      
    1.    

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

Есть ли что-либо подобное в clojure?

4b9b3361

Ответ 1

Продолжается работа над этим с унификацией в библиотеке core.match(https://github.com/clojure/core.match).

В зависимости от того, что вы хотите сделать, другим распространенным способом является использование defmulti/defmethod для отправки на произвольные функции. См. http://clojuredocs.org/clojure_core/clojure.core/defmulti (внизу эта страница является факториалом)

Ответ 2

Я хочу представить defun, это макрос для определения функций с сопоставлением с образцом, как и erlang, на основе core.match. Вышеупомянутую функцию фактов можно записать в:

(use 'defun)
(defun fact
  ([0] 1)
  ([(n :guard #(> % 0))] 
    (* n (fact (dec n)))))

Другой пример: аккумулятор от нуля до положительного числа n:

(defun accum
  ([0 ret] ret)
  ([n ret] (recur (dec n) (+ n ret)))
  ([n] (recur n 0)))

Подробнее см. https://github.com/killme2008/defun

Ответ 3

core.match - полнофункциональная библиотека расширяемого шаблона для Clojure. С небольшой макро магии, и вы, вероятно, можете получить довольно близкое приближение к тому, что вы ищете.

Ответ 4

Кроме того, если вы хотите выделить только простые структуры, такие как векторы и карты (любая вещь, которая является последовательностью или картой, например, запись, на самом деле), вы также можете использовать destructuring bind. Это более слабая форма соответствия шаблонов, но все же очень полезна. Несмотря на то, что он описан в разделе let там, он может использоваться во многих контекстах, включая определения функций.