(partial apply str) 和 clojure 中的 apply-str ->
如果我执行以下操作:
user=> (-> ["1" "2"] (partial apply str))
#<core$partial__5034$fn__5040 clojure.core$partial__5034$fn__5040@d4dd758>
...我会恢复部分功能。但是,如果我将它绑定到变量:
user=> (def apply-str (partial apply str))
#'user/apply-str
user=> (-> ["1" "2" "3"] apply-str)
"123"
...代码将按我的预期工作。我认为它们是同一件事,但显然情况并非如此。有人可以解释为什么这对我来说吗?
If I do the following:
user=> (-> ["1" "2"] (partial apply str))
#<core$partial__5034$fn__5040 clojure.core$partial__5034$fn__5040@d4dd758>
...I get a partial function back. However, if I bind it to a variable:
user=> (def apply-str (partial apply str))
#'user/apply-str
user=> (-> ["1" "2" "3"] apply-str)
"123"
...the code works as I intended it. I would assume that they are the same thing, but apparently that isn't the case. Can someone explain why this is to me?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
->是一个宏,因此它不必遵循您在应用方面期望的规则。宏在评估表单之前转换源。尝试宏扩展形式:
您想通过使用“->”来实现什么目的宏?
编辑:请注意:
-> is a macro, so it doesn't have to follow the rules you would expect in terms of application. The macro transforms the source before the forms are evaluated. Try macroexpanding the forms:
What are you trying to achieve here by using the '->' macro?
EDIT: Note that:
你根本不必这样做。
为什么不这样做呢?
You don't have to do that at all.
Why not do that instead?
第一个表达式
(-> ["1" "2"] (partial apply str))
扩展为:(partial ["1" "2"] apply str)< /code> 基本上意味着:
使用 Vars
apply< 从
["1" "2"]
创建一个函数(这也是一个函数,因为向量是索引键的函数!) /code> 和str
已作为前两个参数提供。该函数被打印为奇怪的#
字符串。仅当调用此函数时,您才会收到 IllegalArgumentException,因为向量仅采用一个整数参数,而不是两个 Var 参数。
The first expression,
(-> ["1" "2"] (partial apply str))
, expands into:(partial ["1" "2"] apply str)
which basically means:Create a function from
["1" "2"]
(which is also a function, since vectors are functions of index keys!) with the Varsapply
andstr
already supplied as the first two arguments. This function gets printed as the weird#<core$partial...>
string.Only when this function will be called will you get an IllegalArgumentException since vectors only take one integer argument, not two Var arguments.
宏 -> 将 expr 作为第二个参数穿过表单。在您的情况下,最终扩展为:
(partial ["1" "2"] apply str)
,创建基于向量的 parital 函数。但是您想要调用基于线程表达式上的 apply 和 str 的 parital 函数,因此需要:
嗯:这段代码非常令人困惑,而且不是惯用的 Clojure。
The Macro -> Threads the expr through the forms as second argument. In your case ends up in expanding to:
(partial ["1" "2"] apply str)
, creating a parital function based on vector.But you want to invoke a parital function based on apply and str on the threaded expr and thus need:
Well: this code i quite confusing and not idiomatic Clojure.
->
宏在第二个版本中的apply-str
周围添加了括号,这就是宏扩展为最终调用您的函数的代码的原因。查看->
的源代码,您可以看到:相关部分是当它处理两个参数时,
x
和form
。如果form
是一个 seq,则x
将作为第二个参数插入到该列表中。否则,宏会将form
和x
放入列表本身。这样您就可以使用一个裸符号作为包含一个符号的列表的简写。The
->
macro adds parens aroundapply-str
in your second version, that's why the macro expands to code that ends up calling your function. Look at the source code for->
and you can see:The relevant part is when it's dealing with two arguments,
x
andform
. Ifform
is a seq,x
is inserted as the second argument in that list. Otherwise, the macro putsform
andx
it into a list itself. This is so you can use a bare symbol as shorthand for a list containing one symbol.