我一直在用 Clojure 中的 monad 进行试验,并提出了以下代码,其中一个 monadic 值/状态对由一个可变的 Clojure deftype 对象表示。
由于对象是可变的,一个优点似乎是您可以编写一元代码,而无需一直构造新的结果对象。
但是,我对 monads 很陌生,所以很想知道:
- 这种结构有意义吗?
- 它真的可以作为 monad 正常工作吗?
下面的代码:
(defprotocol PStateStore
(set-store-state [ss v])
(get-store-state [ss])
(set-store-value [ss v])
(get-store-value [ss]))
(deftype StateStore [^{:unsynchronized-mutable true} value
^{:unsynchronized-mutable true} state]
PStateStore
(get-store-state [ss] (.state ss))
(get-store-value [ss] (.value ss))
(set-store-state [ss v] (set! state v))
(set-store-value [ss v] (set! value v))
Object
(toString [ss] (str "value=" (.value ss) ", state=" (.state ss))))
(defn state-store [v s] (StateStore. v s))
(defmonad MStoredState
[m-result (fn [v]
(fn [^StateStore ss]
(do
(set-store-value ss v)
ss)))
m-bind (fn [a f]
(fn [^StateStore ss]
(do
(a ss)
((f (get-store-value ss)) ss))))])
; Usage examples
(def mb
(domonad MStoredState
[a (m-result 1)
b (m-result 5)]
(+ a b)))
(def ssa (state-store 100 101))
(mb ssa)
; => #<StateStore value=6, state=101>