Пользовательская семантика равенства для структур данных Immutable.js

Я бы хотел, чтобы Sanctuary предоставил Fantasy Land- совместимые типы Map и Set с семантикой равенства на основе значений. В идеале эти значения должны быть неизменными, хотя это не критично, поскольку Sanctuary предоставляет чистые функции для слияния и иного манипулирования этими значениями.

Я хотел бы использовать хорошую работу, проделанную командой Immutable.js; Я предполагаю, что реализация постоянных структур данных требует значительных усилий!

API, предоставляемый Immutable.js, не имеет большого значения, так как Sanctuary предоставляет функции для взаимодействия с этими значениями. Тем не менее, семантика равенства этих типов имеет решающее значение.

Это неприемлемо для моего варианта использования:

> 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, но я не вижу хуков для настройки.

Возможно, что тип карты Sanctuary может обернуть тип карты Immutable.js. Это обеспечит:

  • способ справиться -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
          , ...
          }

Я хотел бы быть уверен, что нет другого способа достичь желаемой семантики равенства перед созданием оболочек, таких как описанные выше. https://github.com/facebook/immutable-js/issues/519 не обещает.

1 ответ

Хотя это было задано давно, я не вижу ссылки на это простое решение:

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, вы получаете равенство значений

Другие вопросы по тегам