A Traversable instance must satisfy 3 laws: Naturality, Identity, Composition. The naturality law states that:
t . traverse f = traverse (t . f)
But for the following examples, this does not hold true.
Example 1
t (Just a) = Left a
f = Just
s = "string"
\> t . traverse f $ s
Left "string"
\> traverse (t . f) s
Left 's'
One might argue that (Either a b) is applicative in b, not in a, but still, this example disproves that the law of naturality is satisfied by the Traversable instance for [].
Example 2
t (head : tail) = replicate 2 head
f = (:[])
s = "string"
\> t . traverse f $ s
["string", "string"]
\> traverse (t.f) s
["string", "string", ...., "string"]
-- a list with 64 elements
-- equivalent to: replicate 64 "string"
This is due to the nature (behaviour) of list`s Applicative instance. It forms a Cartesian product between the lists.
So, for the ZipList datatype this law holds, because it's Applicative instance behaves differently (one could say 'properly' - from the point of view of traverse and sequenceA respecting their Naturality laws).
Could someone clarify to me what am I doing/ seeing wrong, so that I could understand why the Traversable instance for [] is law-abiding?