Nie tak daleko, jak wiem. Musisz napisać funkcję przechodzenia przez wykres.
Najpierw zdecyduj, gdzie przerwać cykliczność. W takim przypadku jest to banalne: użyj nazw węzłów (zakładając, że są one unikalne na wykresie). Dla bardziej złożonej struktury, takiej jak wykres z węzłami i krawędziami jako oddzielnymi typami, trzeba by zdecydować, czy przechowywać krawędzie z węzłami, węzłami z krawędziami, czy też utrzymać węzły i krawędzie całkowicie oddzielone.
Następnie należy wyliczyć wszystkie węzły na wykresie. W tym przypadku oczywistym sposobem jest przechodzenie przez wykres zbierający węzły na skończonej mapie (patrz Data.Map). Następnie zapisz każdy węzeł jako nazwę, a następnie listę innych nazw węzłów.
Odzyskiwanie wykresu oznacza użycie wzoru "wiązania węzła". Odczytaj zapisany wykres w strukturze [(String, [String])]. Następnie oryginalny wykres można zrekonstruować z następującego kodu:
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
zanotować wzajemnej rekursji: tabela nazywa makeNode, która wywołuje findNode, która wywołuje tabeli. Thanks to lazy evaluation this does the Right Thing.
Edycja: kod teraz testowany i nieznacznie rozszerzony.