[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
    :: (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


More information about the Haskell-Cafe mailing list