generalized algebraic datatypes