Formally, `A + B` is isomorphic to `forall T. (A -> T, B -> T) -> T`, where the inner `(A -> T, B -> T)` is the type of a visitor.
a + b
-- CPS transform
= forall t. ((a + b) -> t) -> t
-- distribute -> over +
= forall t. (a -> t, b -> t) -> t
-- if you want to drop even the product, distribute -> over *
-- but this loses you the ability to name a separable Visitor
= forall t. (a -> t) -> (b -> t) -> t
type Visitor a b t = (a -> t, b -> t)
type Sum a b = forall t. Visitor a b t -> t
iso :: Sum a b -> (a + b)
iso s = s (Left, Right)
osi :: (a + b) -> Sum a b
osi (Left a) = \(onA, onB) -> onA a
osi (Right b) = \(onA, onB) -> onB b