web-dev-qa-db-ja.com

Clojureのパターンマッチング機能?

私は過去にerlangを使用しましたが、パターンマッチング関数や「関数ガード」などの非常に便利な機能がいくつかあります。 erlangドキュメントの例は次のとおりです。

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

しかし、これは、パラメーターの形式とその中の値が一致する、はるかに複雑な例に拡張できます。

Clojureに似たものはありますか?

29
mikkom

Core.match( https://github.com/clojure/core.match )ライブラリで、これを統合して行うための作業が進行中です。

実行したい内容に応じて、別の一般的な方法は、defmulti/defmethodを使用して任意の関数をディスパッチすることです。 http://clojuredocs.org/clojure_core/clojure.core/defmulti を参照してください(そのページの下部に階乗の例があります)

30
gilesc

紹介したい 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 を参照してください。

15
killme2008

core.match は、Clojure用のフル機能で拡張可能なパターンマッチングライブラリです。少しのマクロ魔法で、あなたはおそらくあなたが探しているものにかなり近い近似を得ることができます。

9
Dave Ray

また、ベクトルやマップ(実際にはレコードなどのシーケンスまたはマップであるもの)のような単純な構造のみを分解したい場合は、 バインドの破棄 を使用することもできます。これはパターンマッチングの弱い形式ですが、それでも非常に便利です。そこのletセクションで説明されていますが、関数定義を含む多くのコンテキストで使用できます。

3