我希望SanctuaryFantasy 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深度转换对象,您可以获得值相等

    07-24 09:51
    查看更多