2017-04-27 6 views
0

ショートバージョンClojureのプロトコル - 派遣のみ多アリティ機能の2-アリティバージョンの

私は2-アリティバージョンのタイプにディスパッチするマルチアリティ機能をしたいが、私は1-たいすべてのタイプで同一のバージョンです。

(例付き)ロングバージョン

私はこのプロトコルを拡張するために、「タイプA」をしたい場合は、私は

次ているこの

(defprotocol foo 
    (bar [d] [d x])) 

ようになりますプロトコルを持っています

(extend-protocol foo 
    TypeA 
    (bar 
    ([d] #(bar d %)) 
    ([d x] (TypeA-fn x)))) 

一部の機能のためにTypeAに固有のTypeA-fn。

私はその後、私はいくつかの機能のタイプB-FNタイプBに固有のため

(extend-protocol foo 
    TypeB 
    (bar 
    ([d] #(bar d %)) 
    ([d x] (TypeB-fn x)))) 

を以下しているこのプロトコルを拡張するために「タイプB」をしたい場合。

私が作成しようとしている効果は、カレーの効果です。

(bar instance-of-TypeA x) 

(bar instance-of-TypeA) 

ながら、たとえば、二重の二重にタイプAをマップする関数を返します。

barの単一のアーリー実装は常に同じですが、複数のアーリー実装はタイプによって異なります。当然のことながら、私はこのプロトコルをsingle-arityバージョンに拡張するたびに自分自身を繰り返すことは望まないので、これを行うための慣用的な方法です。私は単一のアーリーバージョンを指定せず、どこでも(部分バーTypeX)を使用すると考えましたが、私は部分的に疲れました。私は新しい関数の内部で元の関数をラップすることができ

提案された解決策 、例えば

(defprotocol foo 
    (bar-method [d x])) 

(extend-protocol foo 
    TypeA 
    (bar-method 
    ([d x] (TypeA-fn x)))) 

(defn bar 
([d] (fn [x] (bar-method d x)) 
([d x] (bar-method d x)) 

が、1つの目的のための2つの関数の導入は、洗練ようです。

+1

マルチメソッドを検討しましたか?また、良い古い '(cond ...)'の式に勝るものはありません。 –

答えて

1

あなたの提案されたソリューションは、私が提案するものです。 1つまたは2つの引数の関数が必要です。 2つの引数の場合は多態的にしたいので、多型ディスパッチを行うものにそのケースを転送することは理にかなっています。

関連する問題