Не так, как я знаю. Вы должны написать функцию обхода графа.
Сначала решите, где разорвать круглость. В этом случае это тривиально: используйте имена узлов (предполагая, что они уникальны в графе). Для более сложной структуры, такой как граф с узлами и ребрами в качестве отдельных типов, вам нужно будет решить, сохранять ли ребра с узлами, узлы с ребрами или хранить узлы и ребра полностью отдельно.
Затем перечислите все узлы на графике. В этом случае очевидным способом является обход узлов, собирающих граф, в конечной карте (см. Data.Map ). Затем сохраните каждый узел как имя, за которым следует список имен других узлов.
Восстановление графа означает использование шаблона «завязывание узла». Считайте сохраненный граф в структуру [(String, [String])]. Затем исходный граф можно восстановить с помощью следующего кода:
import qualified Data.Map as M
data Node = Node String [Node]
instance Show Node where
show (Node name others) = "Node " ++ show name ++
" " ++ show (map nodeName others)
where nodeName (Node n _) = n
restoreGraph :: [(String, [String])] -> M.Map String Node
restoreGraph pairs = table
where
table = M.fromList $ map makeNode pairs
makeNode (name, others) = (name, Node name $ map findNode others)
findNode str = fromJust $ M.lookup str table
Обратите внимание на взаимную рекурсию: таблица вызывает makeNode, который вызывает findNode, который вызывает таблицу. Благодаря ленивым оценкам это правильно делает .
Редактировать: код теперь протестирован и немного расширен.