Допустим, у меня есть набор отношений, который выглядит следующим образом:
relations :: [(A, B)]
instance Monoid A
instance Monoid B
Я хочу преобразовать этот набор отношений в новый набор отношений A
с и B
с..
Теперь, вот такие хитрые вещи:
A
s, которые равны, должны иметь свои B
s mappend
ed. B
равных должны иметь свои A
s mappend
ed. - Повторять до тех пор, пока все
A
s и B
s не будут различны (или нет, в зависимости от того, может ли это бытькак-то не итеративно).
РЕДАКТИРОВАТЬ: ограничение порядка упорядочило проблему, поэтому я ее убрал.
Можно предположить, что Ord
, Hashable
или все, что вам нужно, доступно.Для всех намерений и целей можно сказать, что A
ведет себя точно как HashSet
и B
ведет себя точно как Vector
(или некоторый другой тип с разумной проверкой размера).
Это означает, что можно предположить, что let s = size (mappend a b); s >= size a; s >= size b
, а a, b :: B; mappend a b /= mappend b a <=> a, b not mempty; a > b => (mappend a c) > b
и т. Д.
Пример того, как произойдет это преобразование (Представьте, что <a, b>
равно Set.fromList [a, b]
)
[(<1>, [a]), (<4>, [d]), (<2>, [b]), (<5>, [e]), (<1>, [b]), (<2>, [a]), (<3>, [c])]
-- Merge `A`s for equal `B`s
[(<1,2>, [a]), (<4>, [d]), (<1,2> [b]), (<5>, [e]), (<3>, [c])]
-- Merge `B`s for equal `A`s
[(<1,2>, [a, b]), (<4>, [d]), (<5>, [e]), (<3>, [c])]
-- All values are distinct, so we're done.
Как это можно сделать максимально эффективным образом (время, пространство)?