### A slightly better function-DOT dsl

24Feb07

In some of the graphs in Bycicling for Collatz (the divisibility graph with lots of arrows and the collatz one with 1, 2 and 4 highlighted) we manipulated the Haskell-generated graph either in the DOT file source or directly in the Graphviz GUI. The structure itself was somewhat confusing, too; the Dot class never managed to justify itself. Here’s a slightly cleaner version of that code to play with:

# bikes.hs

module Bikes where

data Arr a = a :-> a
instance Functor Arr where fmap f (x:->y) = f  x :-> f y
instance (Show a) => Show (Arr a) where show (x:->y) = show x ++ " -> " ++ show y
arr f = (\x-> x :-> f x)
rra f = (\x-> f x :-> x)
data YellowGraph a = YG {
why :: (a->Bool),
func :: (a -> a),
space :: [a]}
instance (Show a) => Show  (YellowGraph a) where
show xs =  finalDot \$ (toColorList xs) ++ (toArrList xs) where
runGraph xs = (map (arr (func xs)) (space xs))
filterGraph xs = (filter (why xs) (space xs))
toArrList xs  = unlineAppend ";"  (runGraph xs)
toColorList  xs = unlineAppend " [color = \"yellow\", style=\"filled\", shape=\"diamond\"];" (filterGraph xs)
finalDot x = "digraph untitled {" ++ x ++ "}"
unlineAppend d  = unlines . map ((++d) . show)
graph f xs = YG { why = const False, func = f, space = xs}

jane = YG { why = even, func = (flip div 3), space = [1..80]}

The why parameter passed to the data constructor when you’re using the full syntax as in the jane example is a predicate that decides whether or not color a node yellow. Simple, color-less graphs can be produced with the auxiliary function graph.