I mistakenly applied length
to a (pa,ir)
and took a little while to find out, because the code would compile!
So I looked up :t length
, which told me that its argument is only required to be a Foldable
.
That's how I found that there's a Foldable
instance for (,)
:
instance Foldable ((,) a) where
foldMap f (_, y) = f y
foldr f z (_, y) = f y z
length _ = 1
null _ = False
which incidentally overrides what would be the automatic definition of length
.
What is a Foldable
instance for (,)
useful for? Especially considering that some of what derives from a minimal definition (null
and length
) of it has been overridden anyway.
One way through which something nontrivial can be done with Foldable ((,) a)
is bringing in the Foldable
instance for Compose
:
ghci> import Data.Functor.Compose
ghci> sum $ Compose [("apple", 1), ("banana", 2), ("orange", 3)]
6
Also, Foldable
happens to be a superclass of Traversable
, which in turn grants us sequenceA
:
ghci> sequenceA ("strawberry", [4, 5, 6])
[("strawberry",4),("strawberry",5),("strawberry",6)]
The perspective these instances suggest is that of (a, b)
values seen as b
values annotated with an a
tag. sequenceA
, then, shifts the tag to the values in the other functorial structure (in the example above, a list).