Eliminating computation structures yields an ordinary C value This is typically achieved via or Singular supports direct extraction via The sum and product payloads pack and copack and supports total value extraction via On fallible carriers is partial it yields the value if present and otherwise throws and differ in whether the structure survives remains inside the carrier or producing a new carried type eliminates the structure the result type is deduced from the branches which must all return the same type permits any branch results that convert to NOTE Note eliminating with heterogeneous branches Because leaves the algebra it must deduce a single result type branches that disagree are rejected When branch types differ specifying a target via accepts branches returning or as each alternative converts implicitly into the parent Application expands one selected level only The call shapes are straightforward Type Eliminated Call Shape code A type InlinedCode code f A type InlinedCode code pack<A B> type InlinedCode code f A B type InlinedCode code pack<> type InlinedCode code f type InlinedCode code std tuple<A B> type InlinedCode code f A B type InlinedCode code copack<A B> type InlinedCode code f A type InlinedCode text or type SimpleText code f B type InlinedCode code copack<pack<A B> C> type InlinedCode code f A B type InlinedCode text or type SimpleText code f C type InlinedCode A whole carrier application cleanly handles both success and error paths into one result type Exhaustiveness is statically constrained If you omit a handler for a possible type the compilation fails is merely a helper final selection always relies on ordinary C overload resolution WARNING Warning catch all handlers defeat exhaustiveness Exhaustiveness is checked against the types your handlers name An unconstrained names all of them so a that later gains an alternative still compiles the new alternative routes into the catch all instead of failing where its branch is missing Where one handler should serve several alternatives name a concept instead of for example and the check still fires for anything the concept does not admit Type tagged elimination Because storage shape and call shape are distinct untagged can erase structural context such as in To preserve context and prevent implicit conversions from conflating different states provides and member functions Eliminating a carrier using passes an explicit state tag as the first argument to the handler followed by the unpacked payload The success arm receives and the success value or alone if while the error arm receives and the error The success arm receives and the value while the empty arm receives & The active alternative arm receives and the payload The arm receives and the value Symmetrically s arm receives alone representing a nullary unit payload TIP Mathematical note elimination of algebraic structures The two eliminations are not dual to one another the dual of coproduct elimination is product introduction pairing and they differ in how much the category determines Coproduct eliminating is canonical Supplying and determines a unique mediating morphism by the universal property and in ordinary C overload resolution is what computes it Product eliminating invokes no universal property a morphism out of a product is just a morphism What supplies is the bridge between the product as stored a and the product as an argument list which C keeps distinct it uncurries Carrier elimination additionally preserves the injections the state tag such as or tells the handler which injection morphism placed the value into the structure apply apply_r copack get just value value bad_expected_access bad_optional_access transform apply transform copack apply apply_r<R> R apply copack apply_r<copack_for<A B C>> A B C copack expected auto test_elimination fn expected<UserId fn copack<Missing>> ex > int return ex apply fn overload UserId return 1 Missing return 0 fn overload auto copack auto MyConcept auto && apply expected<int int> libfn apply_type apply_type_r apply_type expected std in_place std in_place void fn unexpect optional std in_place std nullopt copack choice std in_place_type<T> just std in_place_type<T> just<void> std in_place_type<void> libfn apply pack apply_type std in_place fn unexpect std in_place_type<T>