## `#[derive(Lattice)]` Macro A struct of multiple lattices can form a _product_ lattice. The simplest case of this is the `Pair` lattice, which is a product of two sub-lattices. For more than two lattices, and/or to improve readability, users can create their own product lattice structs, where each field is a sub-lattice, and use the `#[derive(Lattice)]` macro to automatically derive the lattice traits. Derives `Merge`, `PartialEq`, `PartialOrd`, `LatticeOrd`, `IsBot`, `IsTop`, and `LatticeFrom`, and therefore `Lattice` too. Alternatively, individual traits can be derived: `#[derive(Merge, LatticeOrd, IsBot, IsTop, LatticeFrom)]`. Note that `LatticeOrd` also derives `PartialEq` and `PartialOrd`. Note that all fields must be lattice types. If any field cannot be a lattice type then the `where` clauses prevent the trait impl from compiling. These derive macros will create a second set of generics to allow conversion and merging between varying types. For example, given this struct: ```rust,ignore #[derive(Lattice)] struct MyLattice where KeySet: Collection, Epoch: Ord, { keys: SetUnion, epoch: Max, } ``` Will create derive macros `impl`s in the form: ```rust,ignore impl Merge> for MyLattice where KeySet: Collection, Epoch: Ord, KeySetOther: Collection, EpochOther: Ord, { // ... } ```