summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreltrac <hi@eltr.ac>2026-10-17 18:09:38 +0800
committereltrac <hi@eltr.ac>2026-10-17 18:09:38 +0800
commit77025680498e956b4e29a6b3b5c1a01cd654c462 (patch)
tree07234729687713373ee0292ef6e58e4f38c5246c
parentd163c2cfc30d1618b502be1afdf4487262530159 (diff)
[edit] fix factual error about higher-order functions
-rw-r--r--content/weekly/101.md10
1 files changed, 8 insertions, 2 deletions
diff --git a/content/weekly/101.md b/content/weekly/101.md
index 095675f6..3db819ae 100644
--- a/content/weekly/101.md
+++ b/content/weekly/101.md
@@ -279,7 +279,7 @@ Jenson 认为开源用户也是在意 UI/UX 体验的。他记得之前向 KDE æ
纯函数不维护内部状态,只是接收参数,所以每个函数都是独立的,每个函数都能被**测试**。如果要测试一个对象,需要先实例化对象,这可能还需要实例化其他的对象,传给这个对象的构造方法才行,复杂的业务逻辑经常需要这么干。测试函数就不一样了,可以轻易地传入假的测试数据,函数的返回值也清晰且可预测,测试断言写起来也容易。
-为了方便函数的组合复用,高阶函数往往很有用。这是文中给的例子,`process-transaction` 是个高阶函数,或者说高度抽象的函数。具体的费率、计算策略等细节,都作为参数传入,高阶函数本身不知道。
+为了方便函数的组合复用,高阶函数往往很有用。这是文中给的例子,`process-transaction` 是个高阶函数,或者说 [Fold](https://zh.wikipedia.org/wiki/Fold_(%E9%AB%98%E9%98%B6%E5%87%BD%E6%95%B0))。
```clojure
(defn process-transaction [transaction calculate-fee]
@@ -293,7 +293,13 @@ Jenson 认为开源用户也是在意 UI/UX 体验的。他记得之前向 KDE æ
(process-transaction {:amount 100} #(* % 0.01)))
```
-我觉得这个例子不太合理,应该把 `payment` 和 `refund` 各自写成 `process-payment` 和 `process-refund` 函数,它们都调用 `process-transaction` 函数,但在内部写好部分参数,只接受 `{:amount 100}` 这一条数据,相当于是“继承”了 `process-transaction` 函数。
+第一个参数为操作对象,余下的参数则是要对操作对象做的变换。高阶函数很方便复用,可以组合起来操作同一个数据对象。
+
+```clojure
+(-> {:amount 100}
+ (process-transaction #(* % 0.02)
+ (process-transaction #(* % 0.01)))
+```
上面这个例子中的 `transaction` 是个映射(map),Clojure 的数据管线常常需要传递各种映射,修改其中的值或者增加新值,然后返回,传递给下一个函数。我一般是用箭头宏 `->` 写数据管线的,这篇文章让我学到了新写法,用返回函数的函数构造管线函数: