[Haskell-cafe] Foldable, Traversable and choosing an order

Viktor Dukhovni ietf-dane at dukhovni.org
Wed Sep 25 17:50:16 UTC 2019

```> On Sep 25, 2019, at 1:03 PM, Juan Casanova <juan.casanova at ed.ac.uk> wrote:
>
> Considering map is just fmap for lists, and that all Traversables must be Functors, why isn't traverse just defined as
>
> traverse_alt :: (Traversable t, Applicative f) => t (f a) -> f (t a)
> traverse_alt = traverse id
>
> and let fmap deal with the mapping of the function? Of course this wouldn't be the implementation, it would be the other way around. Instances of Traversable would implement traverse_alt, and then whenever I wanted to do what traverse currently does, I would just do: traverse_alt (fmap f inputs). What is there to gain by including the mapping into the traversal *in the implementation of traverse itself*?

It seems you're reinventing 'sequenceA':

λ> import Data.Traversable

λ> :t traverse id
traverse id :: (Applicative f, Traversable t) => t (f b) -> f (t b)

λ> :t sequenceA
sequenceA :: (Applicative f, Traversable t) => t (f a) -> f (t a)

λ> :t traverse
traverse
:: (Applicative f, Traversable t) => (a -> f b) -> t a -> f (t b)

λ> :t ((sequenceA .) . fmap)
((sequenceA .) . fmap)
:: (Applicative f, Traversable t) => (a1 -> f a) -> t a1 -> f (t a)

Each of 'traverse' and 'sequenceA' can be defined in terms of the other.
The choice of one vs. the other is a matter of convenience:

sequenceA = traverse id
traverse f = sequenceA . fmap f

--
Viktor.

```