1

さて、関数のリストがあるとしましょう: [f1 f2 f3]

変換関数もあります。これを「trans」と呼びます

私がやりたいことは、元のリストのすべての関数に trans を適用し、キーが元の fxn 名に対応するシンボルであり、値がそれらの関数の変換されたバージョンであるマップを返すことです。

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

これはおそらく非常に簡単な質問ですが、関数名をシンボルに変換するために必要なメタデータを取得するのに苦労しています。

4

2 に答える 2

2

最初のリストに実際の関数が含まれていて、Var がそのような Var に解決される関数またはシンボルを保持しているのとは対照的に、Clojure の関数は必ずしも名前を持っていない可能性があるため、一般にそれらに名前を割り当てる標準的な方法はありません。関数オブジェクトのクラスの名前を取り、それをclj-stacktrace のように処理して人間が読める「名前」のようなものを取得することはできますが、そこから関数に移動することはできない場合があります。そのため、関数のリストを扱うときは、名前の明示的なリストを提供することを検討してください。

リストに代わりに記号が含まれている場合は、次のことができます

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

ここで、 のメンバーをキーとして、変換された関数を のメンバーによって名前が付けられた変数に値として格納されfsたマップを作成するための入力リストです。(質問テキストに表示される目的の出力に一致するように記号をキーワードに変換したい場合は、 の最初の引数として使用できます。)fsfs(map keyword fs)zipmap

同様に、Var のリストがある場合、Var から名前空間と記号名を抽出できます (相互運用フォームを使用して の関連フィールドclojure.lang.Var、つまりsymおよびにアクセスしますns) 。(厳密に言えば、Var には名前空間やシンボリック名が関連付けられていない可能性があります -- を参照してください。ただし、そのような Var はあまり頻繁に使用されないため、リスト変換のコントラクトの一部にすることができます。入力。)dereftranswith-local-vars

于 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 に答える