8

Clojureでは、部分関数を返​​す関数のアリティを減らしたバージョンを定義すると便利な場合があります。

(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デザインと見なされますか?

4

3 に答える 3

9

カリー化された関数を作成するために使用することは、 Explicitpartialの概念に基づいています(ほとんどの場合:))。そして、Clojure、Pythonなどの動的に型付けされた言語でこの概念がより適用可能/使用されるのは、型シグネチャ/静的型付けが欠落しているためである可能性があることを発見しました。

于 2012-05-21T04:04:02.963 に答える
7

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

デフォルトで呼び出しがカレーされない環境でカレー関数を作成すると、概念の不一致が生じると思います。この構造は、読者に混乱を引き起こす可能性があります(つまり、コードの人間の読者を意味します)。

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

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

于 2012-05-21T08:45:06.113 に答える
6

partialうーん...個人的には、何が起こっているのかが明確になるので、私はむしろ見たいと思います。

それが「良い」または「悪い」コーディングスタイルかどうかはわかりませんが、既存のClojureコードでこのスタイルを見たことがなく、APIを使用する人々は両方(prefix "foo" 78979)を期待(prefix "foo")して同じ種類のオブジェクトを返すと想像できます。

両方の関数の違いを明確にするために、代わりに次のようなことを行うことができます。

(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"
于 2012-05-21T02:28:05.397 に答える