У меня есть запись, описывающая граф как набор узлов и ребер:
data MyGraph a = MyGraph {
nodes :: Set a,
edges :: Set (a,a),
components :: UnionFindM a -- ?
}
emptyGraph = MyGraph{
nodes = empty, edges = empty,
components = emptyUnionFind singleton union --?
}
addEdge g (a,b) = g{
edges = (a,b) `insert` (edges g),
components = (components g) >>= (equate a b) -- ?
}
Поскольку я никогда не буду удалять ребра, я хочу отслеживать связанные компоненты, используя структуру поиска объединения (которую я мог бы легко обновить при добавлении ребра), потому что я хочу отображать связанные компоненты, поэтому было бы полезно держите их также как набор наборов. И, конечно же, я хочу получить компонент для узла.
Я нашел эквивалентность библиотеку, которую я выбрал, потому что не представляю, как создавать наборы с помощью union-find и persistent- эквивалентность должна знать диапазон значений.
Теперь я могу создавать отношения и возвращать набор наборов, используя:
import Control.Monad(liftM)
import Data.Equivalence.Monad
import Data.Set(singleton, union, fromList)
f = runEquivM singleton union $ do
equate "foo" "bar"
equate "bar" "baz"
(liftM fromList) $ mapM classDesc ["foo","bar","baz","one","two"]
>>> f
fromList [fromList ["bar","baz","foo"],fromList ["one"],fromList ["two"]]
Но: использование fromList
очень наивно, должна быть возможность получить все классы эквивалентности напрямую из внутренней структуры данных.
И, что более важно: как я могу сохранить отношение эквивалентности в своей структуре данных?