Clojure:我如何获取函数列表,转换它们,并返回带有它们原始名称的映射?

Clojure:我如何获取函数列表,转换它们,并返回带有它们原始名称的映射?,clojure,Clojure,好的,假设我有一个函数列表: [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)}

这可能是一个非常简单的问题,但我在获取将函数名转换为符号所需的元数据时遇到了困难。

如果您的初始列表包含实际函数,而不是包含解析为此类变量的函数或符号的变量,则通常没有规范的方法为它们指定名称,Clojure中的as函数不一定有名称。您可以获取函数对象的类的名称,并像处理它一样处理它,以获得类似于人类可读的“名称”,但可能无法从该名称转到函数。因此,在处理函数列表时,您可能需要考虑提供一个明确的名称列表。 如果列表中包含符号,则可以执行以下操作:

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


类似地,如果您有一个Vars列表,您可以从Vars中提取名称空间和符号名称(使用interop表单访问
clojure.lang.Var
的相关字段,即
sym
ns
),同时使用
deref
获取要馈送到
trans
的函数。(严格来说,一个变量可能没有名称空间或符号名附加到它上——请参见
与本地变量的关系
;但是,这样的变量并不经常使用,因此您可以合理地将其作为列表转换契约的一部分,它希望在其输入中找不到任何变量。)

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

(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))