Where the carried types compare equal in a constant expression the laws are checked by the compiler itself Functor identity and monad left identity are machine checked below the remaining laws hold structurally by construction of the derived types Other properties hold structurally Functor composition equals Monad right identity equals Monad associativity equals For graded expected both sides of the associativity derive the same normalized union grade Product associativity Holds after canonical normalization Coproduct set semantics Union associativity commutativity and idempotence apply Coherent widening Upcasting an error through intermediate supersets yields the same final type as upcasting directly to the broadest superset Identity cluster binds Laws hold across and via the canonical payload preserving state shape correspondence constexpr auto test_laws > void constexpr fn expected<int fn copack<Missing>> ex 42 Functor Identity mapping with identity yields the same value constexpr auto id auto v return v static_assert ex | fn transform id ex Monad Left Identity pure x >> f is equivalent to f x constexpr auto pure int v return fn expected<int fn copack<Missing>> v constexpr auto f int v return fn expected<int fn copack<Missing>> v * 2 static_assert pure 42 | fn and_then f f 42 m | transform f | transform g m | transform auto v return g f v m | and_then pure m m | and_then f | and_then g m | and_then auto v return f v | and_then g pack just choice expected<T copack<>>