➕ Sum Types
What are they?
Sum types are quite literally a "sum" of types. The idea is that you take one or more types and put them together in an either/or combination. A sum type is a type that is inhabited by the values of an enumeration of other types.
#![allow(unused)] fn main() { enum Bool { True, False, } let no = Bool::False; }
#![allow(unused)] fn main() { enum Bit { On, Off, } let on = Bit::On; }
But why stop there?! We can nest the values of sum types:
#![allow(unused)] fn main() { enum Bool { True, False, } enum Bit { On, Off, } enum BoolOrBit { Bool(Bool), Bit(Bit), } let off = BoolOrBit::Bit(Bit::Off); }
Now again, but with generics:
#![allow(unused)] fn main() { enum Bool { True, False, } enum Bit { On, Off, } enum Either<A, B> { Left(A), Right(B), } let off: Either<Bool, Bit> = Either::Right(Bit::Off); }
In the above example you can really start to see why they are called "sum types".
The possible values in Either<A, B>
are literally the sum of the values in A
and
the values in B
.
✖️ Product Types
The existance of sum types implies that there exists "product" types, where the possible values in a type are a product of others. Indeed, Rust's struct and tuple types are product types:
#![allow(unused)] fn main() { enum Bool { True, False, } enum Bit { On, Off, } struct BoolAndBit { boolean: Bool, bit: Bit, } }
#![allow(unused)] fn main() { enum Bool { True, False, } enum Bit { On, Off, } let false_off: (Bool, Bit) = (Bool::False, Bit::Off); }
You can see here that a tuple of type (A, B)
will have A * B
value inhabitants.
So for our (Bool, Bit)
type that would be 2 * 2
, or 4 different combinations.
Combine them all
You can even use a short hand for enumerated structs:
#![allow(unused)] fn main() { enum Things { Cat { name: String, is_a_prince: bool, }, Mantis { fly_heads_consumed: u32, }, Bool(bool), } }