【问题标题】:Is this a sensible monad for mutable state in Clojure?这是 Clojure 中可变状态的明智单子吗?
【发布时间】:2011-04-28 03:42:38
【问题描述】:

我一直在 Clojure 中尝试使用 monad,并提出了以下代码,其中 monadic 值/状态对由可变的 Clojure deftype 对象表示。

由于对象是可变的,一个优点似乎是您可以编写一元代码,而无需一直构造新的结果对象。

但是,我对 monad 还很陌生,所以很想知道:

  • 这个结构有意义吗?
  • 它真的可以作为一个 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>

【问题讨论】:

    标签: java functional-programming clojure monads mutable


    【解决方案1】:

    不,它不能作为 monad 正常工作,因为您使用可变状态。

    假设你有一个单子值m(一个值,携带一个状态),你称之为StateStore。你希望能够做到这一点:

    (let
       [a (incr-state m)
        b (decr-state m)]
      (if some-condition a b))
    

    我期望这个计算返回单子m,根据some-condition,其状态是递增或递减。如果您使用可变状态,则在评估此代码期间它会同时递增和递减。

    monad 的优点之一是,虽然它们表示效果,但它们的行为类似于普通的纯、非可变值。您可以传递它们,复制它们(您可以扩展任何let-定义一元值,在每个使用站点用它的定义替换它的名称)。您唯一需要注意的地方是您使用m-bind 实际链接 效果的地方。否则,在代码的不相关部分中没有隐式的效果链接,就像在通常的命令式编程中一样。在您想要限制副作用的情况下,这就是让推理更容易和更舒适的原因。

    编辑

    您可能听说过 monadic 定律,这是任何 monad 实现都应该尊重的方程式。但是,这里的问题不在于您违反了法律,因为法律没有谈论这一点。事实上,一元定律通常用纯语言 Haskell 来表述,因此不考虑副作用。

    如果您愿意,您可以将其视为第四条不言而喻的 monad 法则:好的 monad 应该尊重 referential transparency

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-07
      • 2020-11-12
      • 2022-11-30
      • 1970-01-01
      • 2015-11-29
      • 2016-06-22
      • 2013-07-24
      • 2010-12-29
      相关资源
      最近更新 更多