gvl*_*sov 2 clojure anonymous-function function-composition
我们可以定义和使用这样的匿名函数:
repl=> (#(+ 10 %) 1)
11
Run Code Online (Sandbox Code Playgroud)
但->宏不会接受这样的匿名功能.假设我想添加10然后乘以2.我会尝试写:
(-> 5 #(+ 10 %) #(* 2 %))
Run Code Online (Sandbox Code Playgroud)
但由于某种原因,这不是正确的代码,正确的代码是
(-> 5 (+ 10) (* 2))
Run Code Online (Sandbox Code Playgroud)
(+ 10)和之间的区别是什么#(+ 10 %),为什么不->接受宏定义的匿名函数#()?
这是我尝试解释的.有两个部分.
首先,匿名文字语法.当您编写时#(+ 10 %),它会扩展为功能类似于以下内容的内容:
(fn [x] (+ 10 x))
Run Code Online (Sandbox Code Playgroud)
对于前者
=> (macroexpand '(#(+ 10 %))
Run Code Online (Sandbox Code Playgroud)
会返回类似的东西:
(fn* [p1__7230#] (+ 10 p1__7230#))
Run Code Online (Sandbox Code Playgroud)
第二部分.当你使用线程宏时,正如文档所说,宏通过将第一个参数作为第二个项插入第一个表单来扩展.如果有更多表单,请将第一个表单作为第二个表单插入 第二个表单,依此类推.
这里的关键术语是第二项.它不关心你提供什么形式的参数,它只会使用该规则进行扩展.
所以,当你使用时,要结合两个点
(-> 5 #(+ 10 %) #(* 2 %))
Run Code Online (Sandbox Code Playgroud)
按照规则,它会扩展为功能上与此类似的东西
(fn (fn 5 [x] (+ 10 x)) [y] (* 2 y))
Run Code Online (Sandbox Code Playgroud)
哪个不编译.
另外,作为旁注,表单(+ 10)不是匿名函数.它是一个部分函数调用,在宏扩展期间使用参数进行更新.而'部分',我的意思是在字面意义上,而不是在函数编程意义上.
更新
要解释为什么它将括号中的匿名文字括起来时(如对问题的评论所述),您可以推断出这两个规则的结果.对于前者
=> (macroexpand '(#(+ 10 %)))
Run Code Online (Sandbox Code Playgroud)
会导致功能相当于
((fn [x] (+ 10 x)))
Run Code Online (Sandbox Code Playgroud)
因此,当一个项目插入其第二个位置时,它看起来就像
((fn [x] (+ 10 x)) 5)
Run Code Online (Sandbox Code Playgroud)
这相当于
(#(+ 10 %) 5)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
86 次 |
| 最近记录: |