0

如果你给一个函数的参数太少,它会抱怨:

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),并且我希望这个新规则适用于每个函数,而不必重写所有函数。有没有办法做到这一点,或者有什么充分的理由不可能/不习惯?

4

3 回答 3

2

你已经回答了你自己的问题,partial是要走的路。您应该更多地解释您的用例,以便给出更好的答案。

此外,map-indexed期望 arity 2 的函数作为第一个参数,集合作为第二个参数。

以下返回一个执行您想要的功能(我猜)。

(defn foo [f] (fn [] (map-indexed f vector)))

编辑

我误解了vectoramalloy 指出的 as 的用法。它不是作为数据的向量,而是作为函数

除了使用fn如上所示和partial前面提到的,也许您可​​以创建一个单字符名称的同义词(或一个非常简单的宏),它将扩展为对partial. 如果你选择$,那就是($ map-indexed vector)

于 2013-03-30T18:20:02.980 回答
1

换能器(将)为序列函数执行此操作,以及其他很酷的事情。

见: http: //blog.cognitect.com/blog/2014/8/6/transducers-are-coming

于 2014-08-06T19:01:27.750 回答
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 对大多数功能的期望,但我认为它在某些情况下可能非常有用。

这种方法也有一些限制。以下是我想到的几个:

  1. 它仅对您编写的函数有用,或者碰巧由也使用该模式的其他人编写。
  2. 当涉及多个参数时,它会引入歧义(即,如果 f 是 2 个或 3 个参数的函数,(fxy)是 f 的完整应用还是部分应用?)
  3. 它也不能真正处理可变参数(你会遇到同样的歧义问题)。

也许更好的方法是引入不同的函数来执行部分应用程序。例如:

(defn partial-f [& args] (apply partial f args))

当然,您会想要选择一个比“partial-f”更好的名称。例如对于地图,您可以使用映射器。对于地图索引,也许索引映射器是有意义的。

于 2013-03-31T02:30:41.047 回答