Use new Tree module to print graphs (doesn't handle loops yet), switch type arguments and generalize the label setter into a label editor that takes a function
This commit is contained in:
parent
5d1907094d
commit
a8f87be2c1
1 changed files with 39 additions and 21 deletions
60
src/Graph.hs
60
src/Graph.hs
|
@ -1,35 +1,52 @@
|
||||||
{-# LANGUAGE NamedFieldPuns #-}
|
{-# LANGUAGE NamedFieldPuns #-}
|
||||||
|
{-# LANGUAGE DeriveFunctor #-}
|
||||||
module Graph (
|
module Graph (
|
||||||
Graph(..)
|
Graph(..)
|
||||||
|
, editLabel
|
||||||
|
, open
|
||||||
|
, rewind
|
||||||
|
, singleton
|
||||||
|
, weave
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Data.Map (Map, (!?))
|
import Data.Map (Map, (!?))
|
||||||
import qualified Data.Map as Map (delete, empty, insert)
|
import qualified Data.Map as Map (delete, empty, insert, toList)
|
||||||
|
import Tree (Tree(..), Structure(..))
|
||||||
|
|
||||||
data Vertex label edge = Vertex {
|
data Vertex edge label = Vertex {
|
||||||
label :: label
|
label :: label
|
||||||
, edges :: Map edge (Vertex label edge)
|
, edges :: Map edge (Vertex edge label)
|
||||||
} deriving Show
|
} deriving (Functor, Show)
|
||||||
|
|
||||||
singleton :: label -> Vertex label edge
|
instance Show edge => Tree (Vertex edge) where
|
||||||
|
getStructure (Vertex {label, edges}) = Node [
|
||||||
|
("(" ++ label ++ ")", Node $ recurseOnEdge <$> Map.toList edges)
|
||||||
|
]
|
||||||
|
where
|
||||||
|
recurseOnEdge (edge, vertex) = (show edge, getStructure vertex)
|
||||||
|
|
||||||
|
singleton :: label -> Vertex edge label
|
||||||
singleton label = Vertex {label, edges = Map.empty}
|
singleton label = Vertex {label, edges = Map.empty}
|
||||||
|
|
||||||
data Zipper label edge = Top | Zipper {
|
data Zipper edge label = Top | Zipper {
|
||||||
origin :: Zipper label edge
|
origin :: Zipper edge label
|
||||||
, from :: label
|
, from :: label
|
||||||
, by :: edge
|
, by :: edge
|
||||||
, siblingEdges :: Map edge (Vertex label edge)
|
, siblingEdges :: Map edge (Vertex edge label)
|
||||||
} deriving Show
|
} deriving (Functor, Show)
|
||||||
|
|
||||||
data Graph label edge = Graph {
|
data Graph edge label = Graph {
|
||||||
focus :: Vertex label edge
|
focus :: Vertex edge label
|
||||||
, context :: Zipper label edge
|
, context :: Zipper edge label
|
||||||
} deriving Show
|
} deriving (Functor, Show)
|
||||||
|
|
||||||
open :: Vertex label edge -> Graph label edge
|
instance (Ord edge, Show edge) => Tree (Graph edge) where
|
||||||
|
getStructure = getStructure . zipUp
|
||||||
|
|
||||||
|
open :: Vertex edge label -> Graph edge label
|
||||||
open focus = Graph {focus, context = Top}
|
open focus = Graph {focus, context = Top}
|
||||||
|
|
||||||
zipUp :: Ord edge => Graph label edge -> Vertex label edge
|
zipUp :: Ord edge => Graph edge label -> Vertex edge label
|
||||||
zipUp graph =
|
zipUp graph =
|
||||||
case context graph of
|
case context graph of
|
||||||
Top -> focus graph
|
Top -> focus graph
|
||||||
|
@ -41,10 +58,10 @@ zipUp graph =
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rewind :: Ord edge => Graph label edge -> Graph label edge
|
rewind :: Ord edge => Graph edge label -> Graph edge label
|
||||||
rewind = open . zipUp
|
rewind = open . zipUp
|
||||||
|
|
||||||
follow :: Ord edge => Graph label edge -> edge -> Maybe (Graph label edge)
|
follow :: Ord edge => Graph edge label -> edge -> Maybe (Graph edge label)
|
||||||
follow (Graph {focus, context}) edge =
|
follow (Graph {focus, context}) edge =
|
||||||
edges focus !? edge >>= \vertex -> Just $ Graph {
|
edges focus !? edge >>= \vertex -> Just $ Graph {
|
||||||
focus = vertex
|
focus = vertex
|
||||||
|
@ -56,7 +73,7 @@ follow (Graph {focus, context}) edge =
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
weave :: (Monoid label, Ord edge) => Graph label edge -> [edge] -> Graph label edge
|
weave :: (Monoid label, Ord edge) => Graph edge label -> [edge] -> Graph edge label
|
||||||
weave = foldl $ \graph edge ->
|
weave = foldl $ \graph edge ->
|
||||||
case graph `follow` edge of
|
case graph `follow` edge of
|
||||||
Nothing -> Graph {
|
Nothing -> Graph {
|
||||||
|
@ -70,5 +87,6 @@ weave = foldl $ \graph edge ->
|
||||||
}
|
}
|
||||||
Just newGraph -> newGraph
|
Just newGraph -> newGraph
|
||||||
|
|
||||||
setLabel :: Graph label edge -> label -> Graph label edge
|
editLabel :: Graph edge label -> (label -> label) -> Graph edge label
|
||||||
setLabel graph newLabel = graph {focus = (focus graph) {label = newLabel}}
|
editLabel graph@(Graph {focus}) labelEditor =
|
||||||
|
graph {focus = focus {label = labelEditor $ label focus}}
|
||||||
|
|
Loading…
Reference in a new issue