-> Clojure 中的运算符
是-> Clojure 中的运算符(这个运算符在 Clojure 中被称为什么?)相当于管道运算符 |>在 F# 中?如果是这样,为什么它需要如此复杂的宏定义,而 (|>) 只是定义为
let inline (|>) x f = f x
或者如果没有,F# 的管道运算符是否存在于 Clojure 中,或者如何在 Clojure 中定义这样的运算符?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不,它们不一样。 Clojure 并不真正需要
|>
因为所有函数调用都包含在列表中,例如(+ 1 2)
:您没有什么魔法可以使1 + 2
独立工作。1->
用于减少嵌套并简化常见模式。例如:Expands to
The 前者通常更容易阅读,因为从概念上讲,您正在对
x
执行一系列操作;前一种代码就是这样“塑造”的,而后者则需要一些精神上的解构才能解决。1 您可以编写一个宏来实现此目的。这个想法是将宏包装在要转换的整个源代码树中,并让它查找
|>
符号;然后它可以将源转换为您想要的形状。 Hiredman 使以一种非常 Haskell 风格的方式编写代码成为可能,他的 功能性包。No, they are not the same. Clojure doesn't really have a need for
|>
because all function calls are enclosed in lists, like(+ 1 2)
: there's no magic you could do to make1 + 2
work in isolation.1->
is for reducing nesting and simplifying common patterns. For example:Expands to
The former is often easier to read, because conceptually you're performing a series of operations on
x
; the former code is "shaped" that way, while the latter needs some mental unraveling to work out.1 You can write a macro that sorta makes this work. The idea is to wrap your macro around the entire source tree that you want to transform, and let it look for
|>
symbols; it can then transform the source into the shape you want. Hiredman has made it possible to write code in a very Haskell-looking way, with his functional package.它称为“线程”运算符。出于性能原因,它被编写为宏而不是普通函数,因此它可以提供良好的语法 - 即它在编译时应用转换。
它比 |> 更强大一些。您所描述的运算符,因为它旨在通过多个函数传递一个值,其中每个连续值都作为以下函数调用的第一个参数“插入”。这是一个有点人为的示例:
如果您想定义一个与您所描述的 F# 运算符完全相同的函数,您可以这样做:
不确定它到底有多有用,但无论如何您都可以:-)
最后,如果您想传递一个通过一系列函数获取值,您始终可以在 clojure 中执行类似以下操作:
It's called the "thread" operator. It's written as a macro as opposed to a normal function for performance reasons and so that it can provide a nice syntax - i.e. it applies the transformation at compile time.
It's somewhat more powerful than the |> operator you describe, as it's intended to pass a value through several functions, where each successive value is "inserted" as the first parameter of the following function calls. Here's a somewhat contrived example:
If you want to define a function exactly like the F# operator you have described, you can do:
Not sure how useful that really is, but there you are anyway :-)
Finally, if you want to pass a value through a sequence of functions, you can always do something like the following in clojure:
还值得注意的是,有一个 ->>宏 会将表单作为最后一个参数进行线程化:
The Joy of Clojure,第 8.1 章稍微讨论了这个主题。
It is also worth noting that there is a ->> macro which will thread the form as the last argument:
The Joy of Clojure, chapter 8.1 talks about this subject a bit.
在阅读源代码时(尤其是说话时),我总是将
->
运算符发音为“线程优先”,将->>
运算符发音为“线程” -最后的”。请记住,现在有一个运算符
as->
,它比->
或->> 更灵活。
形式为:值
val
被求值并分配给占位符name
,用户可以将其放置在以下形式的任何位置。我通常选择“it”这个词作为占位符。我们可以像这样模仿线程优先->
:我们可以像这样模仿线程最后
->>
:或者,我们可以将它们组合在一个表达式中:
我经常使用最后一种形式,我在 it-> ="noreferrer">图珀洛库:
When reading source code (especially when speaking), I always pronounce the
->
operator as "thread-first", and the->>
operator as "thread-last".Keep in mind that there is now an operator
as->
which is more flexible than either->
or->>.
The form is:The value
val
is evaluated and assigned to the placeholder symbolname
, which the user can place in ANY position in the following forms. I usually choose the word "it" for the placeholder symbol. We can mimic thread-first->
like so:We can mimic thread-last
->>
like so:Or, we can combine them in a single expression:
I use this last form so much I have made a new operator
it->
in the Tupelo Library: