I have heard people talking a lot about Algebraic Data Types (not to be confused with "Abstract Data Types") in functional programming. All I know is that ADT refers to some kind of composite (often recursive) data types like trees or math expressions.
In Wikipedia, it's only said that:
an algebraic data type is a kind of composite type, i.e., a type formed by combining other types. Two common classes of algebraic types are product types (i.e., tuples and records) and sum types (i.e. tagged or disjoint unions, or variant types).
But no formal definition is given.
So I am wondering what exactly is the definition of ADT? As per Wikipedia, product types and sum types are two examples of ADT, but are product and sum the only valid operations for defining ADT? Are there other operations which are also allowed?