Generalized Algebraic Data Type (GADT) allows each constructor to have customized return type.
Here is an OCaml example from Real World OCaml:
type _ value =
| Int : int -> int value
| Bool : bool -> bool value
type _ expr =
| Value : 'a value -> 'a expr
| Eq : int expr * int expr -> bool expr
| Plus : int expr * int expr -> int expr
| If : bool expr * 'a expr * 'a expr -> 'a expr