{-# LANGUAGE OverloadedStrings #-}
module Cauldron.Graph.Export
(
Doc,
isEmpty,
literal,
render,
(<+>),
brackets,
doubleQuotes,
indent,
unlines,
export,
)
where
import Cauldron.Graph (AdjacencyMap, edgeList, vertexList)
import Data.Foldable (fold)
import Data.String hiding (unlines)
import Prelude hiding (unlines)
newtype Doc s = Doc [s] deriving (Semigroup (Doc s)
Doc s
Semigroup (Doc s) =>
Doc s
-> (Doc s -> Doc s -> Doc s)
-> ([Doc s] -> Doc s)
-> Monoid (Doc s)
[Doc s] -> Doc s
Doc s -> Doc s -> Doc s
forall s. Semigroup (Doc s)
forall s. Doc s
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall s. [Doc s] -> Doc s
forall s. Doc s -> Doc s -> Doc s
$cmempty :: forall s. Doc s
mempty :: Doc s
$cmappend :: forall s. Doc s -> Doc s -> Doc s
mappend :: Doc s -> Doc s -> Doc s
$cmconcat :: forall s. [Doc s] -> Doc s
mconcat :: [Doc s] -> Doc s
Monoid, NonEmpty (Doc s) -> Doc s
Doc s -> Doc s -> Doc s
(Doc s -> Doc s -> Doc s)
-> (NonEmpty (Doc s) -> Doc s)
-> (forall b. Integral b => b -> Doc s -> Doc s)
-> Semigroup (Doc s)
forall b. Integral b => b -> Doc s -> Doc s
forall s. NonEmpty (Doc s) -> Doc s
forall s. Doc s -> Doc s -> Doc s
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall s b. Integral b => b -> Doc s -> Doc s
$c<> :: forall s. Doc s -> Doc s -> Doc s
<> :: Doc s -> Doc s -> Doc s
$csconcat :: forall s. NonEmpty (Doc s) -> Doc s
sconcat :: NonEmpty (Doc s) -> Doc s
$cstimes :: forall s b. Integral b => b -> Doc s -> Doc s
stimes :: forall b. Integral b => b -> Doc s -> Doc s
Semigroup)
instance (Monoid s, Show s) => Show (Doc s) where
show :: Doc s -> String
show = s -> String
forall a. Show a => a -> String
show (s -> String) -> (Doc s -> s) -> Doc s -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc s -> s
forall s. Monoid s => Doc s -> s
render
instance (Monoid s, Eq s) => Eq (Doc s) where
Doc s
x == :: Doc s -> Doc s -> Bool
== Doc s
y
| Doc s -> Bool
forall s. Doc s -> Bool
isEmpty Doc s
x = Doc s -> Bool
forall s. Doc s -> Bool
isEmpty Doc s
y
| Doc s -> Bool
forall s. Doc s -> Bool
isEmpty Doc s
y = Bool
False
| Bool
otherwise = Doc s -> s
forall s. Monoid s => Doc s -> s
render Doc s
x s -> s -> Bool
forall a. Eq a => a -> a -> Bool
== Doc s -> s
forall s. Monoid s => Doc s -> s
render Doc s
y
instance (Monoid s, Ord s) => Ord (Doc s) where
compare :: Doc s -> Doc s -> Ordering
compare Doc s
x Doc s
y
| Doc s -> Bool
forall s. Doc s -> Bool
isEmpty Doc s
x = if Doc s -> Bool
forall s. Doc s -> Bool
isEmpty Doc s
y then Ordering
EQ else Ordering
LT
| Doc s -> Bool
forall s. Doc s -> Bool
isEmpty Doc s
y = Ordering
GT
| Bool
otherwise = s -> s -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Doc s -> s
forall s. Monoid s => Doc s -> s
render Doc s
x) (Doc s -> s
forall s. Monoid s => Doc s -> s
render Doc s
y)
instance (IsString s) => IsString (Doc s) where
fromString :: String -> Doc s
fromString = s -> Doc s
forall s. s -> Doc s
literal (s -> Doc s) -> (String -> s) -> String -> Doc s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> s
forall a. IsString a => String -> a
fromString
isEmpty :: Doc s -> Bool
isEmpty :: forall s. Doc s -> Bool
isEmpty (Doc [s]
xs) = [s] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [s]
xs
literal :: s -> Doc s
literal :: forall s. s -> Doc s
literal = [s] -> Doc s
forall s. [s] -> Doc s
Doc ([s] -> Doc s) -> (s -> [s]) -> s -> Doc s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> [s]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure
render :: (Monoid s) => Doc s -> s
render :: forall s. Monoid s => Doc s -> s
render (Doc [s]
x) = [s] -> s
forall m. Monoid m => [m] -> m
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold [s]
x
(<+>) :: (IsString s) => Doc s -> Doc s -> Doc s
Doc s
x <+> :: forall s. IsString s => Doc s -> Doc s -> Doc s
<+> Doc s
y
| Doc s -> Bool
forall s. Doc s -> Bool
isEmpty Doc s
x = Doc s
y
| Doc s -> Bool
forall s. Doc s -> Bool
isEmpty Doc s
y = Doc s
x
| Bool
otherwise = Doc s
x Doc s -> Doc s -> Doc s
forall a. Semigroup a => a -> a -> a
<> Doc s
" " Doc s -> Doc s -> Doc s
forall a. Semigroup a => a -> a -> a
<> Doc s
y
infixl 7 <+>
brackets :: (IsString s) => Doc s -> Doc s
brackets :: forall s. IsString s => Doc s -> Doc s
brackets Doc s
x = Doc s
"[" Doc s -> Doc s -> Doc s
forall a. Semigroup a => a -> a -> a
<> Doc s
x Doc s -> Doc s -> Doc s
forall a. Semigroup a => a -> a -> a
<> Doc s
"]"
doubleQuotes :: (IsString s) => Doc s -> Doc s
doubleQuotes :: forall s. IsString s => Doc s -> Doc s
doubleQuotes Doc s
x = Doc s
"\"" Doc s -> Doc s -> Doc s
forall a. Semigroup a => a -> a -> a
<> Doc s
x Doc s -> Doc s -> Doc s
forall a. Semigroup a => a -> a -> a
<> Doc s
"\""
indent :: (IsString s) => Int -> Doc s -> Doc s
indent :: forall s. IsString s => Int -> Doc s -> Doc s
indent Int
spaces Doc s
x = String -> Doc s
forall a. IsString a => String -> a
fromString (Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
spaces Char
' ') Doc s -> Doc s -> Doc s
forall a. Semigroup a => a -> a -> a
<> Doc s
x
unlines :: (IsString s) => [Doc s] -> Doc s
unlines :: forall s. IsString s => [Doc s] -> Doc s
unlines [] = Doc s
forall a. Monoid a => a
mempty
unlines (Doc s
x : [Doc s]
xs) = Doc s
x Doc s -> Doc s -> Doc s
forall a. Semigroup a => a -> a -> a
<> Doc s
"\n" Doc s -> Doc s -> Doc s
forall a. Semigroup a => a -> a -> a
<> [Doc s] -> Doc s
forall s. IsString s => [Doc s] -> Doc s
unlines [Doc s]
xs
export :: (Ord a) => (a -> Doc s) -> (a -> a -> Doc s) -> AdjacencyMap a -> Doc s
export :: forall a s.
Ord a =>
(a -> Doc s) -> (a -> a -> Doc s) -> AdjacencyMap a -> Doc s
export a -> Doc s
v a -> a -> Doc s
e AdjacencyMap a
adjMap = Doc s
vDoc Doc s -> Doc s -> Doc s
forall a. Semigroup a => a -> a -> a
<> Doc s
eDoc
where
vDoc :: Doc s
vDoc = [Doc s] -> Doc s
forall m. Monoid m => [m] -> m
mconcat ([Doc s] -> Doc s) -> [Doc s] -> Doc s
forall a b. (a -> b) -> a -> b
$ (a -> Doc s) -> [a] -> [Doc s]
forall a b. (a -> b) -> [a] -> [b]
map a -> Doc s
v (AdjacencyMap a -> [a]
forall a. AdjacencyMap a -> [a]
vertexList AdjacencyMap a
adjMap)
eDoc :: Doc s
eDoc = [Doc s] -> Doc s
forall m. Monoid m => [m] -> m
mconcat ([Doc s] -> Doc s) -> [Doc s] -> Doc s
forall a b. (a -> b) -> a -> b
$ ((a, a) -> Doc s) -> [(a, a)] -> [Doc s]
forall a b. (a -> b) -> [a] -> [b]
map ((a -> a -> Doc s) -> (a, a) -> Doc s
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry a -> a -> Doc s
e) (AdjacencyMap a -> [(a, a)]
forall a. AdjacencyMap a -> [(a, a)]
edgeList AdjacencyMap a
adjMap)