2012-05-21 3 views
8

私は時々Clojureで関数の縮小されたアーリーバージョンを定義するのが便利であることが分かりました。reduce arity partial functionsを定義する

(defn prefix 
    ([pre string] 
    (str pre ":" string)) 

    ([pre] 
    (fn [string] 
     (prefix pre string)))) 

これは、どちらかを行うことができますことを意味します

(prefix "foo" 78979) 
=> "foo:78979" 

((prefix "foo") 78979) 
=> "foo:78979" 

これは非常にHaskellのっぽいようで、部分関数を作成するpartialの必要性を回避します。

しかし、Lispでは良いコーディングスタイル/ APIデザインと考えられていますか?

+0

これはカリングです、はい?役に立つと思う。そして、私はここのインターフェイスを改善できると思います。このテクニックを一般的にすることができればうれしいでしょう。つまり、すべてのキーワードを持つ関数の場合、不完全なキーワードセットでその関数を呼び出すと、残りのすべてのキーワードを受け入れるクロージャが返されます。すべてのキーワードが使用されると、関数の値が取得されます。私はこれが最適化技術として使われているのを見ることができました。 –

+0

私はそれが以下のように定義したときに読みやすさのために部分名を付けても、それは理想的だと思います:(def prefix(partial ...))これは参照する名前と明示的です。今はdefnを使用していませんが、def- partialはあなたのために関数を作成しています。 – KIMA

答えて

7

関数がデフォルトでカレー化されている言語では、関数呼び出しもカレー化されています。 1つが (f a b c)と書くと、言語は(((f a) b) c)と解釈します。これはClojureのケースではありません。

私はコールは、デフォルトではカリー化されていない環境でカリー化関数を作ることは概念的な不一致を作成すると信じている - この構造はおそらく(私はあなたのコードの人間の読者を意味する)読者の混乱を引き起こします

あなたの関数の場合引数が2つ以上ある場合、その定義はすばやく醜くなります。ある関数に4つの引数があるとします。 curryingコールを完全にエミュレートするには、誰かが最初に2つの引数を渡し、残りの2つを最初に渡すと、((f a b) c d)のようなケースを処理する必要があります。この場合、2引数の関数のオーバーロードされたバージョンは、1つまたは2つの引数を取得するかどうかによって異なる動作をするオーバーロードされた関数を返す必要があります。私はそれをマクロで自動化することは可能だと思いますが、それでもなおです。

また、デフォルトの引数と& rest構造を定義する可能性もなくなります。

+0

デフォルトの引数と可変の&rest関数 – 6502

+0

@ 6502はい。完全性のために編集されました。 –

6

hmmm ...個人的には、私はむしろpartialを参照してください。

"良い"か "悪い"コーディングスタイルか分かりませんが、以前のClojureコードでこのスタイルを見たことはありませんでしたが、APIを使用している人は(prefix "foo" 78979)(prefix "foo")同じ種類のオブジェクトを返します。両方の機能の違いを作るために

は、あなたの代わりにこのような何かを行うことができますクリア:カリー化関数を作成するpartialを使用し

(defn prefix [pre string] 
    (str pre ":" string)) 

(defn prefix-fn [pre] 
    (fn [string] 
    (prefix pre string))) 

(prefix "foo" 78979)  ; => "foo:78979" 
((prefix-fn "foo") 78979) ; => "foo:78979" 
+2

"以前はこのスタイルをClojureの既存のコードで見たことがありませんでした" --- Hickeyの新しいreducersライブラリのすべてです。 –

+0

あなたは正しいです、それを指摘してくれてありがとう。 – Gert

9

明示の概念に基づいており、ほとんどの場合、(優れています: ))。 Clojure、Pythonなどの動的型指定言語でより適用可能/使用されるというこのコンセプトは、型シグニチャが欠落している/静的型付けが原因である可能性があることが分かりました。

関連する問題