I suspect that all applicative, foldable monoids are traversable in the same manner. In other words, for any type t :: * -> * that satisfies Applicative and Foldable, and for which all instantiations t a satisfy Monoid, there is a free instance of Traversable.
Here is how I would implement sequenceA:
sequenceA :: (Applicative t, Foldable t, Monoid (t a), Applicative f) =>
t (f a) -> f (t a)
sequenceA = foldl (liftA2 $ \b a -> mappend b (pure a)) (pure mempty)
We can e.g. use this to traverse a list containing functions into a function that will produce a list (since [] is applicative, foldable, and a monoid for all types [a]):
sequenceA [\a -> 2 * a, \a -> 2 + a] $ 5
-- [10, 7]
Unfortunately, I can't figure out how to actually specify a Traversable instance with this implementation of sequenceA. Here's what I tried:
instance (Applicative t, Foldable t, Monoid (t a)) => Traversable t where
sequenceA = foldl (liftA2 $ \b a -> mappend b (pure a)) (pure mempty)
If I try to compile this without any extensions I get:
<interactive>:3:55: error:
• Illegal instance declaration for ‘Traversable t’
(All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
Use FlexibleInstances if you want to disable this.)
• In the instance declaration for ‘(Traversable t)’
What is the correct way for me to express this instance in Haskell?
On the off chance that recursively adding whatever extensions the compiler errors mention might fix the problem, I tried that out and have pasted the results here. If any of the error messages there are relevant, please let me know and I'll move them directly into the question body.
FlexibleInstances? - Fyodor Soikin