我们有some->
和some->>
,它们非常适合用作管道,其中nil
是终止值,但有许多时候你可能希望管道以更多信息终止。
例如,在工作中,我们有一个图像处理管道,每个步骤要么生成增强的图像信息,要么生成一个错误哈希表,解释管道无法继续的原因。我们目前必须显式地将错误检查编码到管道的每个步骤中。
添加接受[pred expr & forms]
的pred->
和pred->>
宏,它们的结构类似于some->
和some->>
,将会使这更简洁。
因此,some->
和some->>
基本上可以是pred-> some?
和pred->> some?
。
(defmacro pred->
"When expr satisfies pred, threads it into the first form (via ->),
and when that result satisfies pred, through the next etc"
[pred expr & forms]
(let [g (gensym)
p pred
steps (map (fn [step] `(if (~p ~g) (-> ~g ~step) ~g))
forms)]
`(let [~g ~expr
~@(interleave (repeat g) (butlast steps))]
~(if (empty? steps)
g
(last steps)))))