math-grads-0.1.5.1: src/Math/Grads/Graph.hs
-- | Module that provides 'Graph' type class and several useful functions
-- for interaction with 'Graph's.
--
module Math.Grads.Graph
( EdgeList
, Graph (..)
, GraphEdge
, changeIndsEdge
, changeTypeEdge
, edgeType
) where
import Data.List (nub)
-- | 'GraphEdge' is just triple, containing index of starting vertex of edge,
-- index of ending vertex of edge and edge's type.
--
type GraphEdge e = (Int, Int, e)
-- | Type alias for list of 'GraphEdge's.
--
type EdgeList e = [GraphEdge e]
-- | Get edge's type from 'GraphEdge'.
--
edgeType :: GraphEdge e -> e
edgeType (_, _, t) = t
-- | Given transformation of edge types transforms 'GraphEdge'.
--
changeTypeEdge :: (e1 -> e2) -> GraphEdge e1 -> GraphEdge e2
changeTypeEdge f (a, b, t) = (a, b, f t)
-- | Given transformation of edge's indices transforms 'GraphEdge'.
--
changeIndsEdge :: (Int -> Int) -> GraphEdge e -> GraphEdge e
changeIndsEdge f (a, b, t) = (f a, f b, t)
-- | Type class that gives data structure properties of graph.
--
class Graph g where
-- | Construct a graph from list of vertices and edges.
--
fromList :: (Ord v, Eq v) => ([v], [GraphEdge e]) -> g v e
-- | Get a list of all vertices and edges from the graph.
--
toList :: (Ord v, Eq v) => g v e -> ([v], [GraphEdge e])
-- | Get the number of vertices.
--
vCount :: g v e -> Int
-- | Unsafe get adjacent vertices.
--
infixl 9 !>
(!>) :: (Ord v, Eq v) => g v e -> v -> [(v, e)]
-- | Unsafe get adjacent indices.
--
infixl 9 !.
(!.) :: g v e -> Int -> [(Int, e)]
-- | Safe get adjacent vertices.
--
infixl 9 ?>
(?>) :: (Ord v, Eq v) => g v e -> v -> Maybe [(v, e)]
-- | Safe get adjacent indices.
--
infixl 9 ?.
(?.) :: g v e -> Int -> Maybe [(Int, e)]
-- | Get a list of edges starting at given vertex.
--
incident :: (Ord v, Eq v) => g v e -> v -> [(v, v, e)]
incident gr at = (\(a, b) -> (at, a, b)) <$> gr !> at
-- | Safe get a list of edges starting at given vertex.
--
safeIncident :: (Ord v, Eq v) => g v e -> v -> Maybe [(v, v, e)]
safeIncident gr at = map (\(a, b) -> (at, a, b)) <$> gr ?> at
-- | Get a list of index edges starting at given vertex.
--
incidentIdx :: (Eq e) => g v e -> Int -> [GraphEdge e]
incidentIdx gr idx = nub ((\(a, b) -> (min idx a, max idx a, b)) <$> gr !. idx)
-- | Safe get a list of index edges starting at given vertex.
--
safeIncidentIdx :: (Eq e) => g v e -> Int -> Maybe [GraphEdge e]
safeIncidentIdx gr idx = nub <$> (map (\(a, b) -> (min idx a, max idx a, b)) <$> gr ?. idx)