@@ -3,11 +3,14 @@ module Data.Graph (
33 Graph (.. ),
44
55 scc ,
6- topSort
6+ scc' ,
7+
8+ topSort ,
9+ topSort'
710 ) where
811
912import Data.Maybe
10- import Data.Array (reverse , concatMap )
13+ import Data.Array (map , reverse , concatMap )
1114import Data.Foldable
1215import Data.Traversable
1316
@@ -25,7 +28,10 @@ data Graph v = Graph [v] [Edge v]
2528type Index = Number
2629
2730scc :: forall v . (Eq v , Ord v ) => Graph v -> [[v ]]
28- scc (Graph vs es) = runPure (runST (do
31+ scc = scc' id
32+
33+ scc' :: forall k v . (Eq k , Ord k ) => (v -> k ) -> Graph v -> [[v ]]
34+ scc' makeKey (Graph vs es) = runPure (runST (do
2935 index <- newSTRef 0
3036 path <- newSTRef []
3137 indexMap <- newSTRef M. empty
@@ -35,11 +41,11 @@ scc (Graph vs es) = runPure (runST (do
3541 (let
3642 indexOf v = do
3743 m <- readSTRef indexMap
38- return $ M. lookup v m
44+ return $ M. lookup (makeKey v) m
3945
4046 lowlinkOf v = do
4147 m <- readSTRef lowlinkMap
42- return $ M. lookup v m
48+ return $ M. lookup (makeKey v) m
4349
4450 go [] = readSTRef components
4551 go (v : vs) = do
@@ -50,13 +56,13 @@ scc (Graph vs es) = runPure (runST (do
5056 strongConnect v = do
5157 i <- readSTRef index
5258
53- modifySTRef indexMap $ M. insert v i
54- modifySTRef lowlinkMap $ M. insert v i
59+ modifySTRef indexMap $ M. insert (makeKey v) i
60+ modifySTRef lowlinkMap $ M. insert (makeKey v) i
5561
5662 writeSTRef index $ i + 1
5763 modifySTRef path $ (:) v
5864
59- for es $ \ (Edge v' w) -> when (v == v') $ do
65+ for es $ \ (Edge v' w) -> when (makeKey v == makeKey v') $ do
6066 wIndex <- indexOf w
6167 currentPath <- readSTRef path
6268
@@ -65,27 +71,27 @@ scc (Graph vs es) = runPure (runST (do
6571 strongConnect w
6672 wLowlink <- lowlinkOf w
6773 for_ wLowlink $ \ lowlink ->
68- modifySTRef lowlinkMap $ M. alter (maybeMin lowlink) v
69- _ -> when (w `elem` currentPath) $ do
74+ modifySTRef lowlinkMap $ M. alter (maybeMin lowlink) (makeKey v)
75+ _ -> when (makeKey w `elem` map makeKey currentPath) $ do
7076 wIndex <- indexOf w
7177 for_ wIndex $ \ index ->
72- modifySTRef lowlinkMap $ M. alter (maybeMin index) v
78+ modifySTRef lowlinkMap $ M. alter (maybeMin index) (makeKey v)
7379
7480 vIndex <- indexOf v
7581 vLowlink <- lowlinkOf v
7682
7783 when (vIndex == vLowlink) $ do
7884 currentPath <- readSTRef path
79- let newPath = popUntil v currentPath []
85+ let newPath = popUntil makeKey v currentPath []
8086 modifySTRef components $ flip (++) [newPath. component]
8187 writeSTRef path newPath. path
8288 return {}
8389 in go vs)))
8490
85- popUntil :: forall v . (Eq v ) => v -> [v ] -> [v ] -> { path :: [v ], component :: [v ] }
86- popUntil _ [] popped = { path: [] , component: popped }
87- popUntil v (w : path) popped | v == w = { path: path, component: w : popped }
88- popUntil v (w : ws) popped = popUntil v ws (w : popped)
91+ popUntil :: forall k v . (Eq k ) => ( v -> k ) - > v -> [v ] -> [v ] -> { path :: [v ], component :: [v ] }
92+ popUntil _ _ [] popped = { path: [] , component: popped }
93+ popUntil makeKey v (w : path) popped | makeKey v == makeKey w = { path: path, component: w : popped }
94+ popUntil makeKey v (w : ws) popped = popUntil makeKey v ws (w : popped)
8995
9096maybeMin :: Index -> Maybe Index -> Maybe Index
9197maybeMin i Nothing = Just i
@@ -95,4 +101,7 @@ maybeMin i (Just j) = Just $ Math.min i j
95101-- Topological sort
96102--
97103topSort :: forall v . (Eq v , Ord v ) => Graph v -> [v ]
98- topSort = reverse <<< concatMap id <<< scc
104+ topSort = topSort' id
105+
106+ topSort' :: forall k v . (Eq k , Ord k ) => (v -> k ) -> Graph v -> [v ]
107+ topSort' makeKey = reverse <<< concatMap id <<< scc' makeKey
0 commit comments