1

精简版

我想要一个多元函数来调度 2 元版本的类型,但我希望 1 元版本在所有类型中都相同。

长版(带示例)

我有一个看起来像这样的协议

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

如果我想要“TypeA”来扩展这个协议,那么我有以下

(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 的函数 TypeB-fn。

我试图创造的效果是柯里化。

(bar instance-of-TypeA x)

是双重的,比如说,虽然

(bar instance-of-TypeA)

返回一个将 TypeA 映射到 double 的函数。

关键是 bar 的单参数实现总是相同的,而多参数实现取决于类型。自然,我不想每次为单参数版本扩展此协议时都重复自己,那么执行此操作的惯用 clojure 方法是什么。我考虑过不指定一个单一的 arity 版本,并在任何地方使用 (partial bar 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))

但是为了一个目的而引入两个功能似乎不优雅。

4

1 回答 1

2

您提出的解决方案正是我的建议。您需要一个或两个参数的函数;在两个参数的情况下,您希望它是多态的,因此将这种情况转发到进行多态调度的东西是有意义的。

于 2017-04-27T07:08:44.693 回答