{-# LANGUAGE TupleSections #-} -- Follow the type and the properties f :: Either a a -> (Bool, a) f = either (False,) (True,) g :: (Bool, a) -> Either a a g (False, a) = Left a g (True, a) = Right a g' :: (Bool, a) -> Either a a g' = uncurry $ cata Right Left where cata :: a -> a -> Bool -> a cata a _ True = a cata _ a False = a -- | -- prop> (f . g) x == x -- prop> (g . f) x == x