Clojure中的 - >運算符(以及Clojure中說的這個運算符是什麼?)等價於F#中的管道運算符?>。如果是這樣,爲什麼它需要在這樣一個複雜的宏定義,(|>)只是定義爲- > Clojure中的運算符
let inline (|>) x f = f x
或者如果沒有,F#的管道運營商存在的Clojure,不然你怎麼會在定義這樣一個操作符Clojure的?
Clojure中的 - >運算符(以及Clojure中說的這個運算符是什麼?)等價於F#中的管道運算符?>。如果是這樣,爲什麼它需要在這樣一個複雜的宏定義,(|>)只是定義爲- > Clojure中的運算符
let inline (|>) x f = f x
或者如果沒有,F#的管道運營商存在的Clojure,不然你怎麼會在定義這樣一個操作符Clojure的?
不,他們是不一樣的。 Clojure並不需要|>
,因爲所有函數調用都包含在列表中,例如(+ 1 2)
:沒有什麼魔法可以使1 + 2
工作處於隔離狀態。
->
是爲了減少嵌套和簡化常見模式。例如:
(-> x (assoc :name "ted") (dissoc :size) (keys))
擴展到
(keys (dissoc (assoc x :name "ted") :size))
前者往往更容易閱讀,因爲從概念上講你在x
執行一系列操作;前面的代碼就是這樣「塑造」的,而後者需要一些精神上的解開來解決。
你可以編寫一個宏來使這個工作。這個想法是把你的宏包裝在你想要轉換的整個源代碼樹上,然後讓它尋找|>
符號;它可以將源代碼轉換成您想要的形狀。 Hiredman用他的functional軟件包以非常好的Haskell編寫代碼。
它被稱爲「線程」運算符。由於性能原因,它被寫爲宏而不是正常函數,因此它可以提供一個很好的語法 - 即它在編譯時應用該變換。
它比你所描述的|>操作符更強大,因爲它旨在通過幾個函數傳遞一個值,其中每個連續值被「插入」爲以下函數調用的第一個參數。這是一個有點做作的例子:
(-> [1]
(concat [2 3 4])
(sum)
((fn [x] (+ x 100.0))))
=> 110.0
如果要定義完全像你所描述的F#操作的功能,你可以這樣做:
(defn |> [x f] (f x))
(|> 3 inc)
=> 4
不知道如何有用這確實是,但有你是無論如何:-)
最後,如果你想通過函數序列傳遞一個值,你總是可以做類似Clojure中的以下內容:
(defn pipeline [x & fns]
((apply comp fns) x))
(pipeline 1 inc inc inc inc)
=> 5
爲什麼你說' - >'是出於性能原因的宏「?這是一個宏,因爲作爲一個功能它是行不通的。 – amalloy 2011-08-18 18:41:08
即使「 - >」是一個函數,但您可以使用( - > a#(...)#(...)#(...)...)實現類似的結果,但它會很慢並且有些醜陋地使用:-) – mikera 2011-08-18 19:07:48
'( - > b(ac)quote)'如果它不是一個宏,它永遠不會評估爲'(quote(abc))'並且還有其他類似的情況。 '#(...)'情況將涉及手動完成所有已經完成的工作,你只是將它製作成另一個版本的「comp」。 – amalloy 2011-08-19 01:13:46
在閱讀源代碼時(特別是說話時),我總是將->
運算符聲明爲「線程優先」,將->>
運算符聲明爲「線程最後」。
請注意,現在有一個操作者as->
比任一->
或->>.
更靈活的形式爲:
(as-> val name (form1 arg1 name arg2)...)
值val
被評估並分配到佔位符符號name
,這對用戶可以以下列形式放置在任何位置。我通常爲佔位符符號選擇單詞「it」。我們可以模仿線程第一->
像這樣:
user=> (-> :a
(vector 1))
[:a 1]
user=> (as-> :a it
(vector it 1))
[:a 1]
我們可以模仿線程最後->>
像這樣:
user=> (->> :a
(vector 2))
[2 :a]
user=> (as-> :a it
(vector 2 it))
[2 :a]
或者,我們可以在一個單一的表達將它們結合起來:
user=> (as-> :a it
(vector it 1)
(vector 2 it))
[2 [:a 1]]
user=> (as-> :a it
(vector it 1)
(vector 2 it)
(vector "first" it "last"))
["first" [2 [:a 1]] "last"]
我明白了。看起來線程運算符在Clojure中很有用,只是因爲Clojure語法的工作方式,但在F#中不會有用。反之亦然,管道運營商。 – 2011-05-26 21:51:44
** Clojure in Action **將第50和51頁中的這些宏的名稱列爲「線程優先」( - >)和「線程最後」( - >>)宏,雖然官方文檔沒有似乎給了他們實際的名字。 – 2012-01-02 03:29:41