When I learn Scala/Haskell, I see there is a concept of Algebraic data type. I\'ve read the explanation from the wikipedia, but I still have a question:
Why does it
Consider the type Bool
. This type, of course, can take on one of two possible values: True or False.
Now consider
data EitherBool = Left Bool | Right Bool
How many values can this type take on? There are 4: Left False, Left True, Right False, Right True
. How about
data EitherBoolInt = Left Bool | Right Int8
Here there are 2 possible values in the Left branch, and 2^8 in the Right branch. For a total of 2 + 2^8 possible values for EitherBoolInt
. It should be easy to see that for any set of constructors and types, this kind of construction will give you a datatype with a space of possible values the size of the sum of the possible values of each individual constructor. For this reason, it's called a sum type.
Consider instead
data BoolAndInt = BAndI Bool Int8
or simply
type BoolAndInt = (Bool, Int)
How many values can this take on? For each possible Int8, there are two BoolAndInts, for a total of 2*2^8 = 2^9 total values. The total number of possible values is the product of the number of values of each field of the constructor, so this is called a product type.
This idea can be extended further -- for example, functions from a->b are an exponential datatype (see The Algebra of Algebraic Datatypes). You can even create a reasonable notion of the derivative of a datatype. This is not even a purely theoretical idea -- it's the basis for the functional construct of "zippers". See The Derivative of a Datatype is the Type of its One-Hole Contexts and The Wikipedia entry on zippers.