
On Sep 25, 2019, at 1:03 PM, Juan Casanova
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.