gpt4 book ai didi

hash - 简单的 Clojure 澄清重新 : hashes/values

转载 作者:行者123 更新时间:2023-12-05 01:03:08 26 4
gpt4 key购买 nike

我刚刚开始使用 Clojure,试图让我的大脑围绕功能/不可变编程。

我的简单问题是 - 我有一个带有两个值的 map ,我想将它们从一个转移到另一个(在同一个 map 内)。这可以用一个简单的函数来完成吗?或者我必须进入ref s 和 atom ?

例如

(def bucket {:volume 100 :rate 10 :poured 0})

我如何搬家 volumepouredrate ?
(defn pour
[bucket]
?
)

; -> {:volume 90 :rate 10 :poured 10}

最佳答案

两者兼而有之。存储桶是一个值,一个函数将获取该值并生成一个基于原始值(和共享未更改值)的新值:

user> (def bucket {:volume 100 :rate 10 :poured 0})
#'user/bucket
user> (assoc bucket
:volume (- (:volume bucket) (:rate bucket))
:poured (+ (:poured bucket) (:rate bucket)))
{:rate 10, :volume 90, :poured 10}

它将原始存储桶留在名为 bucket 的变量中
user> bucket
{:rate 10, :volume 100, :poured 0}

所以我们可以在存储桶值上定义一个函数:
user> (defn pour [bucket]
(assoc bucket
:volume (- (:volume bucket) (:rate bucket))
:poured (+ (:poured bucket) (:rate bucket))))
#'user/pour

user> (pour bucket)
{:rate 10, :volume 90, :poured 10}
user> bucket
{:rate 10, :volume 100, :poured 0}

当我们想要表达桶“身份”的想法时,这将非常有用。安 identity carries values from state to state以一种非常有用的方式。我将使用原子,因为我希望一次对单个标识/事物进行同步更新。
user> (def bucket (atom {:volume 100 :rate 10 :poured 0}))
#'user/bucket

user> (swap! bucket pour)
{:rate 10, :volume 90, :poured 10}

user> (swap! bucket pour)
{:rate 10, :volume 80, :poured 20}

user> (swap! bucket pour)
{:rate 10, :volume 70, :poured 30}

现在我们的桶随着时间的推移而变化,这些变化对每个人都是可行的。值得注意的是,产生新值的函数完全独立于它被用来改变原子并且可以在其他地方重用的事实。一些 Clojurians 将其称为“ simple

通常,您会想要计算诸如“将桶倒三遍的结果是什么”这样的值,这可以通过将每次调用 pour 嵌套在下一个中来很好地表达,如下所示:
user> (pour (pour (pour bucket)))
{:rate 10, :volume 70, :poured 30}

这种模式很常见,有一个两个字符的宏来表达它: ->
user> (-> bucket pour pour pour)
{:rate 10, :volume 70, :poured 30}

在实践中,我看到 clojure 通过嵌套和线程编写函数比通过可变状态系统(原子、引用、代理、变量)更频繁

关于hash - 简单的 Clojure 澄清重新 : hashes/values,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25295568/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com