fromAdjacencyIntMap :: AIM.AdjacencyIntMap -> GraphKL Int
fromAdjacencyIntMap aim = GraphKL
    { toGraphKL    = g
    , fromVertexKL = \x -> case r x of (_, v, _) -> v
    , toVertexKL   = t }
  where
    (g, r, t) = KL.graphFromEdges [ ((), x, ys) | (x, ys) <- AIM.adjacencyList aim ]

-- | Compute the /depth-first search/ forest of a graph.
--
-- In the following examples we will use the helper function:
--
-- @
-- (%) :: (GraphKL Int -> a) -> 'AM.AdjacencyMap' Int -> a
-- a % g = a $ 'fromAdjacencyMap' g
-- @
--
-- for greater clarity.
--
-- @
-- 'AM.forest' (dfsForest % 'AM.edge' 1 1)           == 'AM.vertex' 1
-- 'AM.forest' (dfsForest % 'AM.edge' 1 2)           == 'AM.edge' 1 2
-- 'AM.forest' (dfsForest % 'AM.edge' 2 1)           == 'AM.vertices' [1, 2]
-- 'AM.isSubgraphOf' ('AM.forest' $ dfsForest % x) x == True
-- dfsForest % 'AM.forest' (dfsForest % x)      == dfsForest % x
-- dfsForest % 'AM.vertices' vs                 == 'map' (\\v -> Node v []) ('Data.List.nub' $ 'Data.List.sort' vs)
-- 'AM.dfsForestFrom' ('AM.vertexList' x) % x        == dfsForest % x
-- dfsForest % (3 * (1 + 4) * (1 + 5))     == [ Node { rootLabel = 1
--                                                   , subForest = [ Node { rootLabel = 5
--                                                                        , subForest = [] }]}
--                                            , Node { rootLabel = 3
--                                                   , subForest = [ Node { rootLabel = 4
--                                                                        , subForest = [] }]}]
-- @
fromAdjacencyIntMap :: AIM.AdjacencyIntMap -> GraphKL Int
fromAdjacencyIntMap aim = GraphKL
    { toGraphKL    = g
    , fromVertexKL = \x -> case r x of (_, v, _) -> v
    , toVertexKL   = t }
  where
    (g, r, t) = KL.graphFromEdges [ ((), x, ys) | (x, ys) <- AIM.adjacencyList aim ]

-- | Compute the /depth-first search/ forest of a graph.
--
-- In the following examples we will use the helper function:
--
-- @
-- (%) :: (GraphKL Int -> a) -> 'AM.AdjacencyMap' Int -> a
-- a % g = a $ 'fromAdjacencyMap' g
-- @
--
-- for greater clarity.
--
-- @
-- 'AM.forest' (dfsForest % 'AM.edge' 1 1)           == 'AM.vertex' 1
-- 'AM.forest' (dfsForest % 'AM.edge' 1 2)           == 'AM.edge' 1 2
-- 'AM.forest' (dfsForest % 'AM.edge' 2 1)           == 'AM.vertices' [1, 2]
-- 'AM.isSubgraphOf' ('AM.forest' $ dfsForest % x) x == True
-- dfsForest % 'AM.forest' (dfsForest % x)      == dfsForest % x
-- dfsForest % 'AM.vertices' vs                 == 'map' (\\v -> Node v []) ('Data.List.nub' $ 'Data.List.sort' vs)
-- 'AM.dfsForestFrom' ('AM.vertexList' x) % x        == dfsForest % x
-- dfsForest % (3 * (1 + 4) * (1 + 5))     == [ Node { rootLabel = 1
--                                                   , subForest = [ Node { rootLabel = 5
--                                                                        , subForest = [] }]}
--                                            , Node { rootLabel = 3
--                                                   , subForest = [ Node { rootLabel = 4
--                                                                        , subForest = [] }]}]
-- @
fromAdjacencyIntMap aim = GraphKL
    { toGraphKL    = g
    , fromVertexKL = \x -> case r x of (_, v, _) -> v
    , toVertexKL   = t }
  where
    (g, r, t) = KL.graphFromEdges [ ((), x, ys) | (x, ys) <- AIM.adjacencyList aim ]

-- | Compute the /depth-first search/ forest of a graph.
--
-- In the following examples we will use the helper function:
--
-- @
-- (%) :: (GraphKL Int -> a) -> 'AM.AdjacencyMap' Int -> a
-- a % g = a $ 'fromAdjacencyMap' g
-- @
--
-- for greater clarity.
--
-- @
-- 'AM.forest' (dfsForest % 'AM.edge' 1 1)           == 'AM.vertex' 1
-- 'AM.forest' (dfsForest % 'AM.edge' 1 2)           == 'AM.edge' 1 2
-- 'AM.forest' (dfsForest % 'AM.edge' 2 1)           == 'AM.vertices' [1, 2]
-- 'AM.isSubgraphOf' ('AM.forest' $ dfsForest % x) x == True
-- dfsForest % 'AM.forest' (dfsForest % x)      == dfsForest % x
-- dfsForest % 'AM.vertices' vs                 == 'map' (\\v -> Node v []) ('Data.List.nub' $ 'Data.List.sort' vs)
-- 'AM.dfsForestFrom' ('AM.vertexList' x) % x        == dfsForest % x
-- dfsForest % (3 * (1 + 4) * (1 + 5))     == [ Node { rootLabel = 1
--                                                   , subForest = [ Node { rootLabel = 5
--                                                                        , subForest = [] }]}
--                                            , Node { rootLabel = 3
--                                                   , subForest = [ Node { rootLabel = 4
--                                                                        , subForest = [] }]}]
-- @