2011-09-07 17 views
6

私はさまざまな計算を延期しようとしています。私は、次の形式の機能を持っている、関数の引数の複数の型

(defn a-fn [a b] 
    (let [a (if (fn? a) 
      a 
      #(identity a)) 

     b (if (fn? b) 
      b 
      #(identity b))] 
    (+ (a) (b)))) 

これは値または値を返す関数、私は-FNを渡すことができ、

(a-fn 1 2)  
(defn x [] 1)  
(defn y [] 2)  
(a-fn x y) 
(a-fn x 2) 

私がやっていることは関数のリストを構築しています(上記のように)いくつかのデータを操作する場合、fnsは他のfnを使って引数を取り出すこともあれば、場合によっては変更しないこともあり、引数として値が割り当てられます。私は、このような行動を起こすためのより良い方法があるのだろうかと疑問に思っていましたか?

答えて

2

は、あなたがやりたいために、よりエレガントな方法があるかもしれませんが、ここでのより一般的なバージョン、少なくともです:

(defn delayed [reducer & fs] 
    (apply reducer (for [f fs] (if (fn? f) (f) f)))) 

(def a-fn (partial delayed +)) 

のでdelayedは、任意の関数や機能/値のリストを取りますが。 Ifはすべてのargsを展開し、それらに関数を適用します。その後、我々は+を使用してa-fnを定義するためにpartialを使用します。

user=> (a-fn 1 2) 
3 
user=> (a-fn (constantly 1) 2) 
3 
user=> (a-fn (constantly 1) 2 4) 
7 

また、それは部分的に使用するのではなく、機能を返すためにdelayedために意味をなさないかもしれません。どちらが良いかを確認してください。 「遅延」より

より良い名前は大歓迎です:)

6

あなたがdelayforceを使用することができます。

user=> (defn a-fn [a b] (+ (force a) (force b))) 
#'user/a-fn 
user=> (a-fn 1 2) 
3 
user=> (def x (delay 1)) 
#'user/x 
user=> (def y (delay 2)) 
#'user/y 
user=> (a-fn x y) 
3 
user=> (a-fn x 2) 
3 

あなたは計算が行われたときにテストする(delay (prn :hello) 1)ような何かをしようとした場合、その印刷の点に注意してください。 Delayオブジェクトはそれを強制します。 (def x (delay ...))は安全ですが、REPLプロンプトにplain (delay ...)と入力するのは安全ではありません。

+0

ニース。遅延/力を忘れました。 –

関連する問題