clojure-china好像上不去了,我也不知道他们在搞什么东西
问题
在 七周七并发 函数式并行 --用折叠实现词频统计这一小节里,定义了一个这样的函数
(defn parallel-frequencies [coll]
(r/fold
(partial merge-with +)
(fn [counts x] (assoc counts x (inc (get counts x 0))))
coll))
这里fold使用的第二个函数让我感到很奇怪,一般使用到归约(reduce)实现频率统计是这样写的
(fn [nums]
(reduce (fn [r x]
(assoc r x (inc (get r x 0))))
{} nums))
倒数第二个参数{}作为保存结果返回 ,一般你得先声明好参数,不然会报错
而fold直接放函数进去了,我不知道这是什么原理
好久没用 Clojure 了,尝试 debug 下
(defn parallel-frequencies [coll]
(r/fold
(partial merge-with +)
(fn [counts x]
(prn counts)
(assoc counts x (inc (get counts x 0))))
coll))
(parallel-frequencies [:a :b :c :a])
nil
{:a 1}
{:a 1, :b 1}
{:a 1, :b 1, :c 1}
{:a 2, :b 1, :c 1}
再去看 fold 定义,最后定位到这里
(defn- foldvec
[v n combinef reducef]
(cond
(empty? v) (combinef)
(<= (count v) n) (reduce reducef (combinef) v)
:else
(let [split (quot (count v) 2)
v1 (subvec v 0 split)
v2 (subvec v split (count v))
fc (fn [child] #(foldvec child n combinef reducef))]
(fjinvoke
#(let [f1 (fc v1)
t2 (fjtask (fc v2))]
(fjfork t2)
(combinef (f1) (fjjoin t2)))))))
如果没提供初始值,就用 (combinef)
((partial merge-with +)) ;; => nil
这样应该就能解答楼主问题。
记得这应该是 Clojure 1.7 在引入 Transducers 时修改的,方便处理初始状态。
PS. 对 Clojure 感兴趣可以加
Telegram:https://t.me/clojurists
这个被墙了,国内资料太少了