Immutable.js数据结构的自定义相等语义 [英] Custom equality semantics for Immutable.js data structures
问题描述
我想 Sanctuary 提供 Fantasy Land - 兼容Map和Set类型,具有基于值的相等语义。理想情况下,这些值是不可变的,尽管这并不重要,因为Sanctuary会为合并和操纵这些值提供纯函数。
I would like Sanctuary to provide Fantasy Land -compatible Map and Set types with value-based equality semantics. Ideally these values would be immutable, though this is not critical since Sanctuary would provide pure functions for merging and otherwise manipulating these values.
我很乐意利用完成的好工作由 Immutable.js 团队组成;我想实现持久性数据结构需要相当大的努力!
I would love to leverage the good work done by the Immutable.js team; I imagine implementing persistent data structures takes considerable effort!
由于Sanctuary会公开与这些值交互的函数,因此Immutable.js提供的API并不重要。但是,这些类型的等式语义是至关重要的。
The API provided by Immutable.js is of little importance since Sanctuary would expose functions for interacting with these values. The equality semantics of these types, though, are crucial.
这对我的用例来说是不可接受的:
This is unacceptable for my use case:
> Map([[[1, 2, 3], 'foo'], [[1, 2, 3], 'bar']])
Map { [1,2,3]: "foo", [1,2,3]: "bar" }
[1, 2,3]
与 [1,2,3]
的值相同。不应该有两个具有相同键的映射条目。
[1, 2, 3]
is the same value as [1, 2, 3]
. It should not be possible to have two map entries with the same key.
-0
的处理也是有问题的:
The handling of -0
is also problematic:
> Immutable.is(Map([[0, 0]]), Map([[-0, -0]]))
true
我意识到可以通过定义 equals
方法来定义自己类型的等同语义,但我希望重新定义相等本机类型的语义,例如Array和Number。 这可能吗?相关文件似乎是 is.js ,但我看不到自定义的钩子。
I realize it's possible to define the equality semantics of one's own types by defining equals
methods, but I wish to redefine the equality semantics of native types such as Array and Number. Is this possible? The relevant file appears to be is.js, but I see no hooks for customization.
Sanctuary的Map类型可能会包装Immutable.js Map类型。这将提供:
It's possible that Sanctuary's Map type could wrap the Immutable.js Map type. This would provide:
- 一种处理
-0
; 的方法 - 在执行
assoc <之前执行基于价值的平等检查的机会/ code>
操作通常会导致重复密钥;和 - 定义各种
fantasy-land /
方法的地方。
- a way to handle
-0
; - an opportunity to perform value-based equality checks before performing an
assoc
operation which would normally result in a duplicate key; and - a place to define the various
fantasy-land/
methods.
或许:
Map k v = { negativeZero :: Maybe v
, value :: ImmutableMap k v
, fantasy-land/equals :: Map k v ~> Map k v -> Boolean
, fantasy-land/map :: Map k v ~> (k -> a) -> Map a v
, fantasy-land/bimap :: Map k v ~> (k -> a, v -> b) -> Map a b
, ...
}
我想成为确保在创建如上所述的包装之前没有其他方法可以获得所需的相等语义。 facebook / immutable-js#519 并不乐观。
I'd like to be sure there's no other way to attain the desired equality semantics before creating wrappers such as the above. facebook/immutable-js#519 isn't promising.
推荐答案
虽然很久以前就提出这个问题,但我没有看到对这个简单解决方案的引用:
Although this was asked long ago I don't see a reference to this simple solution:
const {Map, fromJS} = Immutable
// instead of this:
console.log(
Map([[[1, 2, 3], 'foo'], [[1, 2, 3], 'bar']]).toString(),
)
// do this:
console.log(
Map(fromJS([[[1, 2, 3], 'foo'], [[1, 2, 3], 'bar']])).toString()
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/4.0.0-rc.12/immutable.min.js"></script>
通过使用 fromJS 你得到的价值相等
By deeply converting the objects using fromJS you get the value equality
这篇关于Immutable.js数据结构的自定义相等语义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!