要应用的功能列表

时间:2017-10-08 17:59:35

标签: clojure

我是clojure的新手,想要完成以下任务:

我有一些带有单个字母名称的函数,一个字符串“commands” 和一个参数arg

(defn A [x] ...)
(defn B [x] ...)
(defn C [x] ...)

我想要一个函数(让我们称之为apply-fns),给定带有函数名称的字符串,按顺序将函数应用于给定的参数:

; commands = "ACCBB"    
(apply-fns commands arg)
;should have the same effect as
(B (B (C (C (A arg)))))

任何帮助表示赞赏

2 个答案:

答案 0 :(得分:2)

作为一个文字精灵,我会准确地告诉你你所要求的:

(defn A [x])
(defn B [x])
(defn C [x])

(def commands "AACCBB")

(defmacro string-fns [arg]
  (let [cs (map (comp symbol str) commands)]
    `(-> ~arg ~@cs)))

(comment

  (macroexpand
   '(string-fns :foo)) ;;=> (B (B (C (C (A (A :foo))))))

  )

然而,没有任何背景,这没有任何意义。你想做什么?

答案 1 :(得分:0)

您的目标是应用一系列功能(按顺序),以便将以下功能应用于前一个功能。结果应该与嵌套表单(即函数调用)相同,如示例所示:(B (B (C (C (A arg)))))

如果你可以使用一系列命令(或者可以从字符串表示"ACCBB"中提取序列),你可以通过减少名为命令在示例中。

(def commands [A C C B B])

(defn apply-all [initial commands]
  (reduce #(%2 %1) initial commands))

更全面的例子:

(defn A [x]
  (str x "A"))

(defn B [x]
  (str x "B"))

(defn C [x]
  (str x "C"))  

(def commands [A C C B B])

(defn apply-all [initial commands]
  (reduce #(%2 %1) initial commands))

user=> (apply-all "" commands)
; => "ACCBB"