# recollections
The splicing module needs these extensions and imports:
```haskell
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DerivingVia #-}
import GHC.Generics (Generically1(..))
```
Given an enumeration of things like
```haskell
data Things
= This
| That
| Something
| Else
| Entirely
deriving (Eq, Ord, Show, Enum, Bounded, Generic)
```
We can derive a record that will behave like a homogenous zip-list of static size:
```haskell
mkCollection ''Things
-- data Collection a = Collection
-- { this, that, something, else', entirely :: a
-- }
-- deriving stock (Eq, Show, Generic1, Functor, Foldable, Traversable)
-- deriving Applicative via (Generically1 Collection)
-- Fill the record with its indices
mkIndices ''Things
```
## Kmettoverse-lite
```haskell
-- Distributive
mkDistribute ''Things
-- collect is
-- Representable
mkIndex ''Things
mkTabulate ''Things
```
## VS
- Vanilla monomorphic records: don't have functor/foldable/traversable/applicative goodies.
- Hand-rolling the functor: be my guest, hand-roll the field enum too, while you're at it.
- `Map Things a`: All fields are mandatory, all keys are known -> lookups are total and O(1). The optional fields are recoverable, with `Collection (Maybe a)`.
- `Things -> a`: The collection can be stored and loaded.
## Gotchas
All the constructors of the tag type must be nullary — anything else is a
compile-time error, since a partial `Collection` would make `index` partial too.
The generated names (`Collection`, `indices`, `distribute`, `index`,
`tabulate`) are fixed, so a tag named e.g. `Index` will clash with them.