如果你给一个函数太少的参数,它会报错:
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)
,我想让这个新规则适用于每个函数,而不必重写所有函数。是否有办法做到这一点,或者是否有一些很好的理由不可能/不习惯?
你已经回答了你自己的问题,partial
是可行的。您应该更多地解释您的用例,以便给出更好的答案。
另外,map-indexed
的第一个参数是数为2的函数,第二个参数是一个集合。
下面的函数返回你想要的(我猜)。
(defn foo [f] (fn [] (map-indexed f vector)))
编辑
正如amalloy指出的那样,我误解了vector
的使用。它不是作为数据的向量,而是作为函数。除了使用上面所示的fn
和前面提到的partial
之外,也许您可以创建一个单字符名称同义词(或一个非常简单的宏),它将扩展为对partial
的调用。如果选择$
,则为($ map-indexed vector)
。
对于您定义的任何函数
都可以这样做(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)))
当然,这可以用一个宏抽象出来,但这就是模式。
我不知道这是不是一个好主意。这可能不是大多数lisper对大多数函数的期望,但我认为它在某些上下文中可能非常有用。这种方法也有一些限制。以下是我想到的一些:
- 它只对你自己写的函数有用,或者碰巧别人也用这种模式写的函数有用。
- 当涉及多重性时,它会引入歧义(即,如果f是2个或3个参数的函数,(f x y)是完整应用还是部分应用?)
- 它也不能真正处理变量性(你会遇到同样的模糊性问题)。
也许更好的方法是引入一个不同的函数来完成部分应用程序。例如:
(defn partial-f [& args] (apply partial f args))
当然,您可能希望选择一个比"partial-f"更好的名称。例如,对于map,您可以使用mapper。对于map-indexed,也许indexed-mapper是有意义的。
换能器(将)做的正是这个序列函数,在其他很酷的东西。
见:http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming