The traverse
and sequenceA
function in Traversable
class must satisfy the following 'naturality' laws:
t . traverse f == traverse (t . f)
t . sequenceA == sequenceA . fmap t
for every 'applicative transformation' t
. But what is it?
It doesn't seem to work for instance Traversable []
for t = tail
:
Prelude> tail . sequenceA $ [[1],[2,3]]
[[1,3]]
Prelude> sequenceA . fmap tail $ [[1],[2,3]]
[]
Nor for t = join (++)
(repeat the list twice):
Prelude Control.Monad> join (++) . sequenceA $ [[1],[2,3]]
[[1,2],[1,3],[1,2],[1,3]]
Prelude Control.Monad> sequenceA . fmap (join (++)) $ [[1],[2,3]]
[[1,2],[1,3],[1,2],[1,3],[1,2],[1,3],[1,2],[1,3]]
So for what t
they are satisfied?
The Hackage page for Data.Traversable defines an applicative transformation as follows.
[A]n applicative transformation is a function
t :: (Applicative f, Applicative g) => f a -> g a
preserving the Applicative operations, i.e.
t (pure x) = pure x t (x <*> y) = t x <*> t y
The simplest example of this would be the identity function. id
is an applicative transformation. A more specific example for lists would be reverse
.
reverse (pure x) = reverse [x] = [x] = pure x
-- (the (<*>) law is more difficult to show)
And you can verify in GHCi that the laws you reference do hold for reverse
.
Prelude> reverse . sequenceA $ [[1], [2,3]]
[[1,3],[1,2]]
Prelude> sequenceA . fmap reverse $ [[1], [2,3]]
[[1,3],[1,2]]
Source: Data.Traversable