data Foo a b = Foo a b data a :-> b = Arrow (a -> b) data (f :* g) a = f a :* g a data (f :+ g) a = L (f a) | R (g a) data a `Arrow` b = Arrow' (a -> b) data (f `Product` g) a = f a `Product` g a data (f `Sum` g) a = L' (f a) | R' (g a)