关于clojure CollReduce协议的问题
最近在看七周七并发模型,现在第三章第三节化简器卡住了,没有函数式编程经验。作者这一章使用了coljure这门语言来实现map reduce并发模型。具体实现的时候用到了clojure的协议,源代码如下(去掉了无关的代码):
(ns reducers.core
(:require [clojure.core.protocols :refer [CollReduce coll-reduce]]
[clojure.core.reducers :refer [CollFold coll-fold]]))
(defn my-reduce
([f coll] (coll-reduce coll f))
([f init coll] (coll-reduce coll f init)))
(defn make-reducer [reducible transformf]
(reify
CollReduce
(coll-reduce [_ f1]
(coll-reduce reducible (transformf f1) (f1)))
(coll-reduce [_ f1 init]
(coll-reduce reducible (transformf f1) init))))
(defn my-map [mapf reducible]
(make-reducer reducible
(fn [reducef]
(fn [acc v]
(reducef acc (mapf v))))))
这里我有几个不是很明白的地方
一、是这个coljure协议本身,以上面的my-reduce为例,书里的例子是这样的:
reducers.core => (my-reduce + [1 2 3 4])
10
书里说coljure协议跟java的接口很像,所以这里的应该是[]这个数据结构本身实现了CollReduce协议吗?
二、是这个复杂的my-map和make-reduce的实现,这里的make-reducer实现了coll-reduce协议,是否是使用了递归?说实话这个实现我是头雾水,完全不明白是怎么工作的。
三、这里咨询一下读过这本书的大佬,是否需要先简单学习一下Clojure?我看作者后面很多章节也使用了Coljure
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
没有看过这本书。从代码来看,试试看回答这个问题:
my-reduce
函数的实现说明 PersistentVector ([]) 扩展过 CollReduce 协议。make-reducer
函数倒并不复杂,它简单地委托(delegate)了 CollReduce 协议实现给参数reducible
(也就是说reducible
是满足CollReduce
协议的)。它的有趣之处是用transformf
参数(这应该是一个 transducer 函数)来对函数f1
包装,从而让make-reducer
支持了 transducer 函数。注意my-map
的实现完全是简化过的clojure.core
中的map
函数,它其实不算复杂,是 transducer 函数的标准写法,但其参数栈的定义次序是有奥秘的,具体解释起来就太长,需要理解 transducer 的设计思路。另外,引用的代码应该本身是试图解释 transducer 的设计实现,因此答案就在你的书中。