2011-11-03 14 views
13

2つのセットの対称差を計算する関数を作成しました(4clojureサイトの問題の1つ)。関数は単体テストを渡しましたが、コードが重複しているので、私が望むほどきれいではありません。Clojureで関数内の関数を定義し、その関数を参照するにはどうすればよいですか?

差分機能が定義され、「インライン」を参照し、私は1つのFNブロックにそれを行う方法がわからないされて
(fn [x y] (set (concat (diff x y) (diff y x)))) 

(fn [x y] (set (concat 
    (keep-indexed #(if (nil? (get y %2)) %2) x) 
    (keep-indexed #(if (nil? (get x %2)) %2) y)))) 

もちろん、私のようなものを好むだろう。 ClojureはLispの(そして一般的には関数型言語は)機能は特に、彼らがオブジェクトであるClojureの最初のクラスのものであるということです作る機能の

(fn [x y] 
    (let [diff (... function body here ...)] 
    (set 
    (concat (diff x y) (diff y x))))) 
+2

4clojureで質問を完了したら、他の人の回答を実際に見ることができます。自分の試行を整える方法を知ることができます。 –

答えて

21

letまたはletfnを使用してください。 (defn name [arg] ...)で関数を作成すると関数がビルドされ、varに格納されるので、後でプログラムのどこからでも見つけることができます。

(def name (fn [arg] ...)) 

今の名前には、広くアクセスできる機能が含まれています。関数は、特に関数内でのみ必要な場合は、変数に格納する必要はありません。その場合、Matt Fenwickの答えと同じように、関数をローカル名にバインドする方が意味があります。

(let [name (fn [agr] ...)] ...) 

letfnマクロは、これをよりエレガントになります。 重要な部分は、関数が物に格納されているオブジェクトであり、必要に応じてコンテナを選択できることを理解することです。

10

ワン:

+1

なぜ「機能が**物**に格納されている**物であることを理解することが重要な部分です」とおっしゃったのですか? 「オブジェクト」と言えば、オブジェクト指向の意味でオブジェクトについて話していると思う人がいるかもしれません。小文字の「オブジェクト」は、ここではより良いかもしれないと思います。 (私はClojureがJVM上で実装されていることを理解しています。多くのものがOOクラスやオブジェクトとして実装されていますが、新しいClojuriansは実装の詳細について考える必要はありません) –

関連する問題