- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
在没有可变状态的 FP 中,每个操作都会返回一个新的世界状态。给定:我有一个联系人列表和一个单独的联系人。
我将德克添加到我的地址簿中。德克是我通讯录中的 child 。我的通讯录是德克的 parent 。因为我不能同时设置两个引用,所以我进退两难。亲子关系应该定义一个无限循环,在这个循环中我可以永远从 parent 到 child 再到 parent 再到同一个 child 。
使用 JavaScript 语法:
var addresses = new AddressBook();
var dirk = new Contact(addresses, 'Dirk', ...);
在第二行,我传递了没有德克的地址簿。德克有一个地址簿的父引用,但他不在其中。
我怀疑答案,但我想确定。我真的要改变状态以正确设置它还是我忽略了一些技术?
最佳答案
如果您希望这种事情像在您的 JavaScript 示例中那样工作(这样您就可以直接在实际的 child 中查找实际的地址簿),您必须使地址簿可变。这甚至不是因为父项和子项的初始创建(可以管理,在某些功能语言中比在其他语言中更容易),而是因为如果您继续添加对地址簿的进一步引用,旧条目将仍然持有他们过时的地址簿版本。
在 Clojure 中,在这种情况下很容易使用 Atom 或 Ref 来保存整个地址簿,然后在每个子项中也放置一个指向地址簿的 Atom 或 Ref,但 Clojure 引用类型只是真正设计用于保存不可变数据并嵌套它们可能会导致问题。
更好的解决方案是为您的实体提供符号名称(关键字、数字、UUID 都可以)并将它们存储在 map 中的某个地方。使用单个原子可能如下所示:
(def state (atom {:contacts {:dirk ...}
:address-books {}}))
然后您可以将 Dirk 添加到新地址簿(以 HashMap 的形式一路创建),如下所示:
(swap! state (fn [state-map]
(update-in state-map [:address-book :my-address-book]
(fn [abook]
(let [entries (get abook :entries [])]
(assoc abook :entries (conj entries :dirk)))))))
请注意,这会以符号引用 (:dirk
) 的形式将 Dirk 添加到地址簿中,以便在 :contacts
下的顶级状态图中查找 key 。如果您还希望 Dirk 联系人维护其所属的地址簿列表,请进一步使用 update-in
向 Dirk 联系人添加适当的信息,可能会删除与 ->
的一些嵌套:
(-> state-map
(update-in [...] ...)
(update-in [...] ...))
关于javascript - 在 FP 中如何设置互惠关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17625770/
我在不同的 h 文件中定义了两个类,每个类都有一些私有(private)函数。但是,我希望能够从另一个类中的函数访问每个类中的一个函数。 例如…… //apple.h: class Beets; cl
假设有必要计算打包浮点数据的倒数或倒数平方根。两者都可以通过以下方式轻松完成: __m128 recip_float4_ieee(__m128 x) { return _mm_div_ps(_mm_s
我是一名优秀的程序员,十分优秀!