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

Reference