Interesting! I have two questions.
(1) Given that Graph is of kind * -> * -> *, rather than (* -> *) -> * -> *, how can I use a GADT? The first graph using existentials defined earlier in this thread looked like:
data Box = forall s. Show s => Box s
type ExQuantGraph = Gr Box String
If instead I use a GADT:
data Box' a where
Bi :: Int -> Box' Int
Bs :: String -> Box' String
then I can't define a graph on
type G = Gr Box' String
because Box is not a concrete type. I could specify (Box a) for some a, but then I lose the polymorphism that was the purpose of the GADT.
(2) Would a GADT be better than what I'm already doing? Currently I define a Mindmap[1] as a graph where the nodes are a wrapper type called Expr ("expression"):
type Mindmap = Gr Expr _ -- the edge type is irrelevant
data Expr = Str String | Fl Float
| Tplt [String] | Rel | Coll
| RelSpecExpr RelVarSpec deriving(Show,Read,Eq,Ord)
I do a lot of pattern matching on those constructors. If I used a GADT I would still be pattern matching on constructors. So do GADTs offer some advantage?