用传感器创建refs

时间:2015-03-11 18:44:52

标签: clojure transducer

是否可以在Clojure中创建一个带有传感器的ref,其方式类似于使用传感器创建chan

即,当您使用传感器创建chan时,它会将所有输入过滤/映射到输出中。

我希望还有一种创建ref的方法,这样无论你设置什么,它都可以忽略或修改输入。这可能吗?

2 个答案:

答案 0 :(得分:2)

向通道添加换能器会在内容通过时修改内容,这大致类似于将指针添加到ref,每次值更改时都会应用自己的更改。这个改变它的自我然后再次触发手表所以小心不要在它们是递归的时候吹掉堆栈。

user> (def r (ref 0))
#'user/r
user> (add-watch r :label
                 (fn [label the-ref old-state new-state]
                   (println "adding that little something extra")
                   (if (< old-state 10) (dosync (commute the-ref inc)))))
#<Ref@1af618c2: 0>
user> (dosync (alter r inc))
adding that little something extra
adding that little something extra
adding that little something extra
adding that little something extra
adding that little something extra
adding that little something extra
adding that little something extra
adding that little something extra
adding that little something extra
adding that little something extra
adding that little something extra
1
user> @r
11

如果需要,您甚至可以将换能器应用于原子的状态。

答案 1 :(得分:1)

这是一个有趣的想法,但至少有几个原因,这是错误的方法。你会失去一些你期望拥有的关系:

(alter r identity) =/= r

(alter r f)(alter r f) =/= (alter r (comp f f))

(alter r f) =/= (ref-set r (f @r))

另外一些传感器是副作用挥发物,并且在dosync区块中没有业务。即如果你使用(take n)作为你的传感器,那么如果dosync失败,那么它将重试,好像用(take (dec n))调用,这违反了dosync身体要求。

问题是ref允许您作为单独的步骤进行读写。相反,如果有一些基础,让你“输入”一个隐藏的“状态”输入并一步一步收集输出,与STM一致,那么这就是可以使用的东西。