2

この問題について考えれば考えるほど、間違っているように思えます...

プログラムで「マップコンストラクター」のようなものを定義しました。この背後にあるアイデアは、いくつかの「アイテム」を処理するための一般的なマップ構造を持っているが、特定の種類のアイテムにいくつかのデフォルトを適用したいということです。

私が抱えている問題は、この「マップ コンストラクター」には kv ペアがあり、そのペアの値は、このマップを使用する関数によって決定される必要があることです (次の例でより明確になる可能性があります)。

私の最初のアイデアは、値で式を引用し、そのeval関数でそれを実行することでした。2 番目のアイデアは、値を に置き換えることでしたfnが、これは引用された式に似たものを返すようです。

問題を描写してみましょう:

  • モデルの結果のマップは {:a 1 :b 2 :c 3} のようになります。
  • コンストラクタは次のようなものです

    (defn cons-field [b]
      {:a (fn [name] (str name "!"))
       :b b
       :c "default"})
    
  • アイテムが作成されます(def a-field (cons-field 5))

  • マップを消費する呼び出し関数は次のようなものです

     (defn the-function [name field]
       (str (get-in field [:a])))
    

今、私が必要としているのは、この :a の値が「the-function」のパラメーター名の関数になることです。もちろん、最後の関数は機能していません。とにかく正しいアプローチであるかどうかはわかりません。':a' キーは常にfn;であるとは限りません。単なる文字列リテラルの場合もあります。何か案は?

乾杯!

4

2 に答える 2

0

これが、A. Webb と Jeremy Heiler のコメントの後で、この問題を解決した方法です。

初期コンストラクターは次のように変更されました。

(defn cons-field [b]
  {:a nil ; either delete completely or comment that
          ; the case will be handled by the caller
   :flag xx ; true or :case-qualifier
   :b b
   :c "default"})

呼び出し関数は次のように変更されました。

(defn the-function [name field]
  (let [case-q (:flag field)]
    (cond
      (= case-q :case-qualifier) (get-name name) ; you can have many different cases
                                              ; conciser using constants for these qualifiers
      (...) ()))) ; else as normal

次に、最初にマップに配置されたロジックが別の関数に入ります。

(defn get-name [name] (str name "!"))

これが他の誰かに役立つことを願っています:)

于 2013-07-02T15:56:12.167 に答える