2011-12-21 24 views
25

He usado erlang en el pasado y tiene algunas cosas realmente útiles como funciones de coincidencia de patrones o "guardias de funciones". Ejemplo de docs Erlang es:Funciones de coincidencia de patrones en Clojure?

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

Pero esto podría ampliarse para un ejemplo mucho más complejo en el que la forma de parámetro y los valores dentro de ella se hacen coincidir.

¿Hay algo similar en clojure?

+0

Esta es una vieja pregunta, pero esto proyecto expande core.match a funciones y es casi exactamente lo que estaba pidiendo hace años https://github.com/killme2008/defun – mikkom

Respuesta

27

Hay un trabajo en curso para hacer esto con la unificación en la biblioteca core.match (https://github.com/clojure/core.match).

Dependiendo de exactamente lo que quiere hacer, otra forma común es usar defmulti/defmethod para despachar funciones arbitrarias. Consulte http://clojuredocs.org/clojure_core/clojure.core/defmulti (en la parte inferior de esa página está el ejemplo factorial)

+3

core.match es casi exactamente lo que estoy buscando en el nivel de código, es esta parte de el núcleo de 1.3 (no entiendo exactamente cómo la c lojure packaging works)? Con algunas macros creo que sería posible extender la sintaxis a las funciones (en mi humilde opinión, el código más claro podría escribirse con funciones de coincidencia de patrones con guardias) – mikkom

+0

Requiere 1.3 pero no es parte de 1.3 de manera predeterminada. Si está utilizando Leiningen (https://github.com/technomancy/leiningen) y debería hacerlo, añada una línea '[org.clojure/core.match' 0.2.0-alpha8 ']' a las dependencias de tu project.clj, luego ejecuta lein deps. Y sí, como puede ver en la parte inferior de su página github, los desarrolladores planean aplicar core.match a funciones (despacho de predicados) pronto. – gilesc

+0

Si alguien más se encuentra con argumentos de función de coincidencia de patrón de problemas, use 'vec': http://nickknowlson.com/blog/2013/02/17/using-core-match-with-function-arguments/ –

9

core.match es una biblioteca de coincidencia de patrones ampliable y con todas las funciones para Clojure. Con un poco de magia macro y probablemente puedas obtener una aproximación muy cercana a lo que estás buscando.

3

Además, si desea separar solo estructuras simples como vectores y mapas (cualquier cosa que sea secuencia o mapa, por ejemplo, registro, de hecho), también podría usar destructuring bind. Esta es la forma más débil de coincidencia de patrones, pero aún así es muy útil. A pesar de que se describe en la sección let allí, se puede usar en muchos contextos, incluidas las definiciones de funciones.

+2

La desestructuración es bastante demasiado limitado para una coincidencia real de patrones. – mikkom

12

quiero introducir defun, es una macro para definir funciones con coincidencia de patrones al igual que Erlang, que está basado en core.match. La función hecho anterior puede ser escrito en:

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

Otro ejemplo, un acumulador de cero a número positivo n:

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

más información, consulte https://github.com/killme2008/defun

+1

¡Eso es hermoso! Buena suerte con el proyecto Estoy seguro de que ayudará a muchas personas ya que las funciones de coincidencia de patrones son una de las cosas menos subestimadas en la programación. – mikkom

+0

@ killme2008, realmente me gusta tu trabajo con defun. ¿Cuáles son las ventajas de defun over core.match? –

Cuestiones relacionadas