好的,假设我有一个函数列表:[f1 f2 f3]
我还有一个转换函数,我们称它为“trans”
我想要做的是将 trans 应用于原始列表中的每个函数,并返回一个映射,其键是与原始 fxn 名称相对应的符号,其值是这些函数的转换版本:
{:f1 (trans f1) :f2 (trans f2) :f3 (trans f3)}
这可能是一个非常简单的问题,但我无法获取将函数名称转换为符号所需的元数据。
好的,假设我有一个函数列表:[f1 f2 f3]
我还有一个转换函数,我们称它为“trans”
我想要做的是将 trans 应用于原始列表中的每个函数,并返回一个映射,其键是与原始 fxn 名称相对应的符号,其值是这些函数的转换版本:
{:f1 (trans f1) :f2 (trans f2) :f3 (trans f3)}
这可能是一个非常简单的问题,但我无法获取将函数名称转换为符号所需的元数据。
如果您的初始列表包含实际函数,而不是 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,即sym和ns),同时使用deref来获取要馈送到的函数trans。(严格来说,一个 Var 可能没有附加名称空间或符号名称 - 请参阅with-local-vars;尽管此类 Var 的使用并不频繁,因此您可以合理地将其作为列表转换合同的一部分,它希望在其输入。)
您可以尝试如下所示的宏。您需要将函数列表直接传递给宏。
(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))