1

好的,假设我有一个函数列表:[f1 f2 f3]

我还有一个转换函数,我们称它为“trans”

我想要做的是将 trans 应用于原始列表中的每个函数,并返回一个映射,其键是与原始 fxn 名称相对应的符号,其值是这些函数的转换版本:

{:f1 (trans f1) :f2 (trans f2) :f3 (trans f3)}

这可能是一个非常简单的问题,但我无法获取将函数名称转换为符号所需的元数据。

4

2 回答 2

2

如果您的初始列表包含实际函数,而不是 Vars 包含解析为此类 Vars 的函数或符号,那么通常没有为它们分配名称的规范方法,因为 Clojure 中的函数可能不一定有名称。您可以获取函数对象的类的名称并像clj-stacktrace那样处理它以获得类似于人类可读的“名称”的东西,但可能无法从该名称转到函数。因此,在处理函数列表时,您可能需要考虑提供一个明确的名称列表。

如果您的列表包含符号,您可以这样做

(zipmap fs (map (comp trans deref resolve) fs))

其中fs是生成映射的输入列表,其中的成员fs作为键,转换后的函数存储在由成员命名的变量中fs作为值。(如果您希望将符号转换为关键字以匹配问题文本中显示的所需输出,则可以将(map keyword fs)其用作 的第一个参数zipmap。)

类似地,如果您有一个 Var 列表,您可以从 Var 中提取名称空间和符号名称(使用互操作表单来访问 的相关字段clojure.lang.Var,即symns),同时使用deref来获取要馈送到的函数trans。(严格来说,一个 Var 可能没有附加名称空间或符号名称 - 请参阅with-local-vars;尽管此类 Var 的使用并不频繁,因此您可以合理地将其作为列表转换合同的一部分,它希望在其输入。)

于 2013-06-15T08:31:17.820 回答
0

您可以尝试如下所示的宏。您需要将函数列表直接传递给宏。

(defmacro fn-to-map [fns trans-fn]
  `~(into {} (map #(-> [(-> % name keyword) `(~trans-fn ~%)]) fns)))

例子:

(let [f1 inc
      f2 dec
      f3 print]
  (fn-to-map [f1 f2 f3] identity))
于 2013-06-15T13:06:05.720 回答