如果你给一个函数的参数太少,它会抱怨:
user=> (map-indexed vector)
ArityException Wrong number of args (1) passed to: core$map-indexed
clojure.lang.AFn.throwArity (AFn.java:437)
假设我想要做一些方便的事情,比如自动调用(partial map-indexed vector)
,我希望这个新规则适用于每个函数,而不必重写所有函数。有没有办法实现这一目标,还是有一些好的理由不可能/不是惯用的?
答案 0 :(得分:2)
您已回答了自己的问题,partial
是可行的方法。您应该更多地解释您的用例,以便给出更好的答案。
此外,map-indexed
期望arity 2的函数作为第一个参数,而集合作为第二个参数。
以下内容返回一个能够执行您想要的功能(我猜)。
(defn foo [f] (fn [] (map-indexed f vector)))
修改强>
我误解了amalloy指出的vector
的使用。它不是矢量数据,而是函数。
除了如上所述使用fn
和前面提到的partial
之外,也许您可以创建一个单字符名称同义词(或一个非常简单的宏),它将扩展为一个调用到partial
。如果您选择$
,则为($ map-indexed vector)
。
答案 1 :(得分:1)
您可以为您定义的任何功能执行类似的操作
(defn f
;; The "real" f
([x y z] (whatever-f-does x y z))
;; Overloads to "automagically" construct partial applications
([x] (partial f x))
([x y] (partial f x y)))
当然,这可以用宏来抽象,但这就是模式。
我不知道这是不是一个好主意。这可能不是大多数Lispers对大多数函数所期望的,但我认为它在某些情况下可能非常有用。
这种方法也有一些限制。以下是我想到的一些内容:
或许更好的方法是引入不同的功能来进行部分应用。例如:
(defn partial-f [& args] (apply partial f args))
当然,您可能希望选择比“partial-f”更好的名称。例如,对于map,您可以使用mapper。对于地图索引,也许索引映射器是有意义的。
答案 2 :(得分:1)
Transducers(will)会为序列函数执行此操作,以及其他很酷的事情。
请参阅:http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming