There is a certain pattern that I happen to reach for quite often:
data Collection a = Collection
{ this, that, something, else', entirely :: a
}
deriving stock (Eq, Show, Generic1, Functor, Foldable, Traversable)
deriving Applicative via (Generically1 Collection) -- this one
That Applicative instance adds so much power for one simple line.
GHC 9.4 brought Generically1 into base, thanks to all the DerivingVia enjoyers out there.
Previously I had to go through distributive+representable, but now it’s almost free.
The only missing thing was the boilerplate to go between the fields and their indices.
The recollections package solves that with some TH:
It was actually even easier to start with the indices:
module Things where
data Things
= This
| That
| Something
| Else
| Entirely
deriving (Eq, Ord, Show, Enum, Bounded, Generic)
And get the Collection above out of it:
mkCollection ''Things
-- Fill the record with its indices:
-- indices :: Collection Things
mkIndices ''Things
The kmettoverse methods can also be derived (and used directly, without the extra deps):
-- Distributive
mkDistribute ''Things
-- Representable
mkIndex ''Things
mkTabulate ''Things