Implementing Traversable for Coproduct Given the following definitions of Functor and Coproduct from fp-course:


class Functor f where
  (&lt;$&gt;) ::
    (a -&gt; b)
    -&gt; f a
    -&gt; f b

class Functor f =&gt; Applicative f where
  pure ::
    a -&gt; f a
  (&lt;*&gt;) ::
    f (a -&gt; b)
    -&gt; f a
    -&gt; f b

class Functor t =&gt; Traversable t where
  traverse ::
    Applicative f =&gt;
    (a -&gt; f b)
    -&gt; t a
    -&gt; f (t b)

data Coproduct f g a =
  InL (f a)
  | InR (g a)



Is there a cleaner or more succinct way to implement the following?

instance (Traversable f, Traversable g) =&gt;
  Traversable (Coproduct f g) where
  traverse ::
    Applicative h =&gt;
    (a -&gt; h b)
    -&gt; Coproduct f g a
    -&gt; h (Coproduct f g b)
  traverse f (InL fa) = InL &lt;$&gt; traverse f fa
  traverse f (InR ga) = InR &lt;$&gt; traverse f ga
Here is how Edward Kmett implemented traverse in the Data.Functor.Coproduct package. 

instance (Traversable f, Traversable g) =&gt; Traversable (Coproduct f g) where
  traverse f = coproduct
    (fmap (Coproduct . Left) . traverse f)
    (fmap (Coproduct . Right) . traverse f)


While he writes in a points free style and uses Either under the hood instead of your bespoke Coproduct instance, the result is still the same.  Apply the supplied function to either the left or right branch and wrap the result back in the constructor.

I do not see a better way to than the implementation given unless η-conversion to points-free is appealing for some reason.