Nice work. One note: what you defined in your example is an algebraic data type, but not a generalized algebraic data type. The data constructors' are implicitly defined, as opposed to being explicitly defined. I liked this wiki page as a guide https://wiki.haskell.org/GADTs_for_dummies