@@ -100,10 +100,10 @@ import Distribution.Utils.Structured (Structure (..), Structured (..))
100100import qualified Data.Array as Array
101101import qualified Data.Foldable as Foldable
102102import qualified Data.Graph as G
103+ import qualified Data.List.NonEmpty as NE
103104import qualified Data.Map.Strict as Map
104105import qualified Data.Set as Set
105106import qualified Data.Tree as Tree
106- import qualified Distribution.Compat.Prelude as Prelude
107107import GHC.Stack (HasCallStack )
108108
109109-- | A graph of nodes @a@. The nodes are expected to have instance
@@ -115,7 +115,7 @@ data Graph a = Graph
115115 , graphAdjoint :: G. Graph
116116 , graphVertexToNode :: G. Vertex -> a
117117 , graphKeyToVertex :: Key a -> Maybe G. Vertex
118- , graphBroken :: [(a , [ Key a ] )]
118+ , graphBroken :: [(a , NonEmpty ( Key a ) )]
119119 }
120120
121121-- NB: Not a Functor! (or Traversable), because you need
@@ -285,7 +285,7 @@ cycles g = [vs | CyclicSCC vs <- stronglyConnComp g]
285285-- | /O(1)/. Return a list of nodes paired with their broken
286286-- neighbors (i.e., neighbor keys which are not in the graph).
287287-- Requires amortized construction of graph.
288- broken :: Graph a -> [(a , [ Key a ] )]
288+ broken :: Graph a -> [(a , NonEmpty ( Key a ) )]
289289broken g = graphBroken g
290290
291291-- | Lookup the immediate neighbors from a key in the graph.
@@ -344,7 +344,7 @@ revTopSort g = map (graphVertexToNode g) $ G.topSort (graphAdjoint g)
344344-- if you can't fulfill this invariant use @'fromList' ('Data.Map.elems' m)@
345345-- instead. The values of the map are assumed to already
346346-- be in WHNF.
347- fromMap :: IsNode a => Map (Key a ) a -> Graph a
347+ fromMap :: forall a . ( IsNode a , Eq ( Key a )) => Map (Key a ) a -> Graph a
348348fromMap m =
349349 Graph
350350 { graphMap = m
@@ -353,17 +353,26 @@ fromMap m =
353353 , graphAdjoint = G. transposeG g
354354 , graphVertexToNode = vertex_to_node
355355 , graphKeyToVertex = key_to_vertex
356- , graphBroken = broke
356+ , graphBroken =
357+ map (\ ns'' -> (fst (NE. head ns''), NE. map snd ns'')) $
358+ NE. groupWith (nodeKey . fst ) $
359+ brokenEdges'
357360 }
358361 where
359- try_key_to_vertex k = maybe (Left k) Right (key_to_vertex k)
362+ brokenEdges' :: [(a , Key a )]
363+ brokenEdges' = concat brokenEdges
360364
365+ brokenEdges :: [[(a , Key a )]]
361366 (brokenEdges, edges) =
362- unzip $
363- [ partitionEithers (map try_key_to_vertex (nodeNeighbors n))
367+ unzip
368+ [ partitionEithers
369+ [ case key_to_vertex n' of
370+ Just v -> Right v
371+ Nothing -> Left (n, n')
372+ | n' <- nodeNeighbors n
373+ ]
364374 | n <- ns
365375 ]
366- broke = filter (not . Prelude. null . snd ) (zip ns brokenEdges)
367376
368377 g = Array. listArray bounds edges
369378
0 commit comments