Насколько я знаю, нет. Вы должны написать функцию обхода графика.
Во-первых, решите, где разбить цикличность. В этом случае это тривиально: используйте имена узлов (при условии, что они уникальны в графе). Для более сложной структуры, такой как граф с узлами и ребрами как отдельными типами, вам придется решить, хранить ли ребра с узлами, узлы с ребрами или хранить узлы и ребра полностью отдельно.
Затем перечислите все узлы в графе. В этом случае очевидным способом является обход узлов графа по конечной карте (см. html" rel="nofollow noreferrer">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
Обратите внимание на взаимную рекурсию: table вызывает makeNode, который вызывает findNode, который вызывает table. Благодаря ленивой оценке это работает правильно.
Изменить: код протестирован и немного расширен.
person
Paul Johnson
schedule
28.12.2008