{-# LANGUAGE TupleSections #-}
module Graph.DirectedGraph where
import qualified Data.Set as Set
import qualified Data.Map as Map
type Graph a = Map.Map a (Set.Set a)
empty :: Ord a => Graph a
empty = Map.empty
insertNode :: Ord a => a -> Graph a -> Graph a
insertNode u g
| Map.member u g = g
| otherwise = Map.insert u Set.empty g
insertEdge :: Ord a => (a, a) -> Graph a -> Graph a
insertEdge (u, v) = Map.insertWith Set.union u (Set.singleton v) . insertNode u . insertNode v
deleteNode :: Ord a => a -> Graph a -> Graph a
deleteNode u = Map.delete u . Map.map (Set.delete u)
adjacentNodes :: Ord a => a -> Graph a -> Maybe (Set.Set a)
adjacentNodes = Map.lookup
nodes :: Ord a => Graph a -> Set.Set a
nodes = Map.keysSet
edges :: Ord a => Graph a -> [(a, a)]
edges = concat . Map.elems . Map.mapWithKey (\u -> map (u,) . Set.toList)
fromList :: Ord a => [(a, a)] -> Graph a
fromList = foldr insertEdge Map.empty
transpose :: Ord a => Graph a -> Graph a
transpose = fromList . map (\(a, b)->(b, a)) . edges