A sum type is a discriminated union of values, and can be thought of as an OR on types.
An ADT is a potentially recursive sum type of product types.
A Witness type describes properties of a sum type's branches at the type level
A GADT is a sum type with one of more witness types, each equiped with a type eqauality