How do I make use of Generalized Algebraic Data Type?
The example given in the haskell wikibook is too short to give me an insight of the real possibilities of GADT.
I like the example in the GHC manual. It's a quick demo of a core GADT idea: that you can embed the type system of a language you're manipulating into Haskell's type system. This lets your Haskell functions assume, and forces them to preserve, that the syntax trees correspond to well-typed programs.
When we define Term, it doesn't matter what types we choose. We could write
data Term a where
...
IsZero :: Term Char -> Term Char
or
...
IsZero :: Term a -> Term b
and the definition of Term would still go through.
It's only once we want to compute on Term, such as in defining eval, that the types matter. We need to have
...
IsZero :: Term Int -> Term Bool
because we need our recursive call to eval to return an Int, and we want to in turn return a Bool.