我希望Sanctuary为Fantasy Land兼容的Map和Set类型提供基于值的相等语义。理想情况下,这些值将是不可变的,尽管这并不关键,因为Sanctuary将提供用于合并和操纵这些值的纯函数。
我想利用Immutable.js小组所做的出色工作;我想实现持久性数据结构需要花费大量精力!
Immutable.js提供的API并不重要,因为Sanctuary会公开用于与这些值进行交互的功能。但是,这些类型的相等语义至关重要。
对于我的用例,这是 Not Acceptable :
> Map([[[1, 2, 3], 'foo'], [[1, 2, 3], 'bar']])
Map { [1,2,3]: "foo", [1,2,3]: "bar" }
[1, 2, 3]
与[1, 2, 3]
的值相同。不可能有两个具有相同键的映射条目。-0
的处理也有问题:> Immutable.is(Map([[0, 0]]), Map([[-0, -0]]))
true
我意识到可以通过定义
equals
方法来定义自己类型的相等语义,但是我希望重新定义本机类型(例如Array和Number)的相等语义。 这可能吗? 相关文件似乎是is.js,但是我没有看到用于自定义的钩子(Hook)。Sanctuary的Map类型可能会包装Immutable.js Map类型。这将提供:
-0
的方法; assoc
操作之前执行基于值的相等性检查,该操作通常会导致键重复;和fantasy-land/
方法的地方。 也许:
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前景不佳。
最佳答案
尽管很久以前就问过这个问题,但我看不到对此简单解决方案的引用:
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深度转换对象,您可以获得值相等