2017-04-27 44 views
0

短版Clojure的協議 - 調度僅適用於多元數函數的2元數版

我想多元數函數派遣的類型爲2元數的版本,但我想1-所有類型的arity版本相同。

龍版(附例)

我有一個協議,如果我想「類型A」來擴展這個協議看起來是這樣的

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

,然後我有以下

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

對於某些特定於TypeA的函數TypeA-fn。

如果我想要「的TypeB」延長本協議的話,我有以下

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

對一些功能的TypeB-FN特定的TypeB。

我試圖創造的效果是柯里化。

(bar instance-of-TypeA x) 

是雙,比如說,而

(bar instance-of-TypeA) 

返回類型A映射到一個雙重功能。

問題是bar的單個arity實現總是相同的,而多個arity實現取決於類型。當然,我不想每次擴展單協議版本的協議時都重複自己,那麼做到這一點的慣用clojure方法是什麼?我曾經考慮過沒有指定一個單獨的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

您是否考慮過multimethods?另外,有時候沒有什麼比擊敗一個古老的'(cond ...)'表達式。 –

回答

1

您提出的解決方案正是我所建議的。你需要一個或兩個參數的函數;在兩個參數的情況下,你希望它是多態的,所以這種情況下轉發到多態派發的東西是有意義的。