1

是否可以ref在 Clojure 中创建带有传感器的 a,类似于chan使用传感器创建 a?

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

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

4

2 回答 2

2

Adding a transducer to a channel modifies the contents as they pass through, which is roughly analogous to adding a watch to a ref that applies it's own change each time the value changes. This change it's self then triggers the watch again so be careful not to blow the stack if they are recursive.

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

You could even apply a transducer to the state of the atom if you wanted.

于 2015-03-12T00:57:06.637 回答
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失败,那么它将重试,就像调用 with 一样(take (dec n)),这违反了dosync身体要求。

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

于 2015-03-12T21:48:03.183 回答