Пользовательская семантика равенства для структур данных 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, вы получаете равенство значений