在Clojure函数中移动参数

Son*_*ton 4 clojure

我正在研究4clojure问题29:"搞定问题"

(= (__ "HeLlO, WoRlD!") "HLOWRD")
Run Code Online (Sandbox Code Playgroud)

我在REPL中写了一个解决方案:

user=> (apply str (filter (fn [foo] (some #(= % foo) 
         (map char (range 65 91)))) "AbC"))
"AC"
Run Code Online (Sandbox Code Playgroud)

但是,你可以看到我的参数"ABC"嵌套两个括号内.我怎么会我的参数移动到外面,所以我可以在4clojure测试中使用它?我是否以错误的方式解决了问题?

huo*_*uon 5

您不需要将a参数移动到外部,您可以使用与创建过滤功能相同的技术,即fn:

(fn [string] 
  (apply str 
    (filter 
      (fn [foo] (some #(= % foo) (map char (range 65 91)))) 
      string)))
Run Code Online (Sandbox Code Playgroud)

作为一个例子,以下两个语句是相同的:

(+ 1 2 3)
((fn [n] (+ 1 2 n)) 3)
Run Code Online (Sandbox Code Playgroud)

但是,要真正回答您的问题,您可以使用comp("撰写")并partial移动参数以允许eta转换(这是您尝试执行的操作的最后部分的技术名称):

(comp (partial apply str)
      (partial filter (fn [foo] (some #(= % foo) 
                                       (map char (range 65 91))))))
Run Code Online (Sandbox Code Playgroud)

此表达式现在是一个函数,它接受一个字符串,过滤大写字母然后将其转换回字符串(通知comp从右到左应用函数).

(注意,最后一个表达可能不是非常惯用的Clojure;第一种方法,或者其他人的建议之一,更好.)