-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Basic type-safe directed acyclic graphs. -- -- This is a type-safe approach for a directed acyclic graph. -- -- Edge construction is incremental, creating a "schema": -- --
--   import Data.Graph.DAG.Edge
--   
--   -- | Edges are statically defined:
--   edges =
--     ECons (Edge :: EdgeValue "foo" "bar") $
--     ECons (Edge :: EdgeValue "bar" "baz") $
--     ECons (Edge :: EdgeValue "foo" "baz")
--     unique -- ENil, but casted for uniquely edged graphs
--   
-- -- The nodes are separate from edges; graph may be not connected: -- --
--   data Cool = AllRight
--             | Radical
--             | SuperDuper
--   
--   graph =
--     GCons "foo" AllRight $
--     GCons "bar" Radical $
--     GCons "baz" SuperDuper $
--     GNil edges
--   
-- -- Some type tomfoolery: -- --
--   *Data.Graph.DAG> :t edges
--   
--   edges
--     :: EdgeSchema
--          '['EdgeType "foo" "bar", 'EdgeType "bar" "baz",
--            'EdgeType "foo" "baz"] -- Type list of edges
--          '['("foo", '["bar", "baz"]), '("bar", '["baz"])] -- potential loops
--          'True -- uniqueness
--   
--   *Data.Graph.DAG> :t getSpanningTrees $ edges
--   
--   getSpanningTrees $ edges
--     :: Data.Proxy.Proxy
--          '['Node "foo" '['Node "bar" '['Node "baz" '[]],
--                          'Node "baz" '[]],
--            'Node "bar" '['Node "baz" '[]],
--            'Node "baz" '[]]
--   
--   *Data.Graph.DAG> reflect $ getSpanningTrees $ edges
--   
--     [Node "foo" [Node "bar" [Node "baz" []]
--                 ,Node "baz" []]
--     ,Node "bar" [Node "baz" []]
--     ,Node "baz" []]
--   
-- -- This library is still very naive, but it will give us compile-time -- enforcement of acyclicity (and uniqueness) in these graphs - ideal for -- dependency graphs. @package dag @version 0.0.2 module Data.Graph.DAG.Edge -- | We use promoted symbol values for the from and to -- type parameters. This is the user-level data type when declaring the -- list of edges. data EdgeValue (from :: Symbol) (to :: Symbol) Edge :: EdgeValue -- | We need this for type-level computation list. data EdgeKind EdgeType :: from -> to -> EdgeKind -- | Some people just want to watch the world burn. Ideally, this shouldn't -- exist; poor error messages, and is very square peg - round hole. -- | not . elem for lists of types, resulting in a constraint. -- | A simple Data.List.lookup function for type maps. -- | Trivial inequality for non-reflexivity of edges -- | Simply reject anything that's been reached in the other direction. We -- expect an explicit type signature when uniqueness is needed, otherwise -- we will wait until invocation to see if the edges are unique. class Acceptable (a :: EdgeKind) (oldLoops :: [(Symbol, [Symbol])]) (unique :: Bool) -- | Add an explicit element to the head of a list, if the test is inside -- that list. -- | Update the exclusion map with the new edge: the from key gets -- to added, likewise with keys that have from in it's -- value list. We need to track if the key exists yet. -- | edges is a list of types with kind EdgeKind, while -- nearLoops is a map of the nodes transitively reachable by -- each node. data EdgeSchema (edges :: [EdgeKind]) (nearLoops :: [(Symbol, [Symbol])]) (unique :: Bool) ENil :: EdgeSchema [] [] unique ECons :: !a -> !(EdgeSchema old oldLoops unique) -> EdgeSchema (b : old) c unique -- | Utility for constructing an EdgeSchema granularly unique :: EdgeSchema [] [] True notUnique :: EdgeSchema [] [] False instance (Excluding from (Lookup to excludeMap), Excluding to (Lookup from excludeMap), from =/= to) => Acceptable ('EdgeType from to) excludeMap 'True instance (Excluding from (Lookup to excludeMap), from =/= to) => Acceptable ('EdgeType from to) excludeMap 'False module Data.Graph.DAG.Edge.Utils -- | Trivial rose tree for creating spanning trees data Tree a_aa2d Node :: a_aa2d -> [Tree a_aa2d] -> Tree a_aa2d type STree (z_aa2w :: Tree a_aa2d) = Sing z_aa2w type NodeSym2 (t_aa2p :: a_aa2d) (t_aa2q :: [] (Tree a_aa2d)) = Node t_aa2p t_aa2q data NodeSym1 (l_aa2u :: a_aa2d) (l_aa2t :: TyFun ([] (Tree a_aa2d)) (Tree a_aa2d)) NodeSym1KindInference :: NodeSym1 data NodeSym0 (l_aa2r :: TyFun a_aa2d (TyFun ([] (Tree a_aa2d)) (Tree a_aa2d) -> *)) NodeSym0KindInference :: NodeSym0 -- | Gives us a generic way to get our spanning trees of the graph, as a -- value. Credit goes to András Kovács. reflect :: (SingI a, SingKind (KProxy :: KProxy k)) => Proxy a -> Demote a -- | Adds an empty c tree to the list of trees uniquely -- | Adds c as a child of any tree with a root t. Assumes -- unique roots. -- | We need to track if from has is a root node or not. TODO: -- Some code repeat. -- | Add to as a child to every from node in the -- accumulator. -- | Auxilliary function normally defined in a where clause for -- manual folding. -- | Expects edges to already be type-safe getSpanningTrees :: EdgeSchema es x unique -> Proxy (SpanningTrees es) instance Show a0 => Show (Tree a0) instance Eq a0 => Eq (Tree a0) instance (SingI n0, SingI n1) => SingI ('Node n0 n1) instance SDecide 'KProxy => SDecide 'KProxy instance SEq 'KProxy => SEq 'KProxy instance SingKind 'KProxy => SingKind 'KProxy instance SuppressUnusedWarnings NodeSym0 instance SuppressUnusedWarnings NodeSym1 instance PEq 'KProxy module Data.Graph.DAG -- | The graph may be not connected data DAG es a GNil :: EdgeSchema es x unique -> DAG es a GCons :: String -> a -> DAG es a -> DAG es a -- | A simple Data.Map.lookup duplicate. glookup :: String -> DAG es a -> Maybe a instance Functor (DAG es)