Generalized algebraic data types (GADTs) are another deep and powerful area of the language. As with polymorphic variant types, much of their true power is exposed when they're used with type parameters. But we can understand their surface syntax and how they relate to regular variant types, for now.
GADTs are, as the name suggests, a generalized form of algebraic data types. The name is a slight misnomer because they are really more of a generalized form of regular variant types only. Algebraic data types is a general name for both product and sum types taken together. Syntactically, GADTs look as follows:
/* src/Ch05/Ch05_GADTs.re */
type poNumber = string;
type paymentMethod =
| Cash: paymentMethod
| PurchaseOrder(poNumber): paymentMethod; /* (1) */
let paymentCash = Cash; /* (2) */
let paymentMessage(paymentMethod) = switch (paymentMethod) ...