# \[ANN\] recollections: fixed-size representable collections

**URL:** https://discourse.haskell.org/t/ann-recollections-fixed-size-representable-collections/14533
**Category:** Announcements
**Created:** [August 8, 2026, 11:17am UTC](https://discourse.haskell.org/t/ann-recollections-fixed-size-representable-collections/14533 "2026-08-08T11:17:53Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![wiz](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/wiz/32/2408_2.png) [@wiz](https://discourse.haskell.org/u/wiz)
#### Post date: [August 8, 2026, 11:17am UTC](https://discourse.haskell.org/t/ann-recollections-fixed-size-representable-collections/14533/1 "2026-08-08T11:17:53Z")

</div>

There is a certain pattern that I happen to reach for quite often:

```haskell
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:

> **[recollections](https://hackage.haskell.org/package/recollections)**
>
> Fixed-size representable (Zippy Applicative) collections.

It was actually even easier to start with the indices:

```haskell
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:

```haskell
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):

```haskell
-- Distributive
mkDistribute ''Things
-- Representable
mkIndex ''Things
mkTabulate ''Things

```

---

<div class="post-metadata">

### Author: ![philh](https://avatars.discourse-cdn.com/v4/letter/p/7ab992/32.png) [@philh](https://discourse.haskell.org/u/philh)
#### Post date: [August 10, 2026, 12:02pm UTC](https://discourse.haskell.org/t/ann-recollections-fixed-size-representable-collections/14533/2 "2026-08-10T12:02:21Z")

</div>

Fwiw I have trouble following the documentation here. Suggestions for how it could be clearer:

- You show what `mkCollection` expands to in the readme, put that in the module-level docs too.
- What does `mkIndices` expand to? (I think `indices :: Collection Things; indices = Collection { this = This, that = That, ... }`?) What’s it useful for?
- What are the type signatures of the generated `distribute`, `index` and `tabulate` functions?
- For `mkDistribute`, the generated html for `distribute` writes `$` instead of `<$>`.

---

<div class="post-metadata">

### Author: ![wiz](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/wiz/32/2408_2.png) [@wiz](https://discourse.haskell.org/u/wiz)
#### Post date: [August 14, 2026, 9:40pm UTC](https://discourse.haskell.org/t/ann-recollections-fixed-size-representable-collections/14533/3 "2026-08-14T21:40:46Z")

</div>

Thanks. The docs are updated: [Data.Recollections.TH](https://hackage-content.haskell.org/package/recollections-0.1.0.0/docs/Data-Recollections-TH.html)

> [@philh](#):
>
> - What does `mkIndices` expand to? (I think `indices :: Collection Things; indices = Collection { this = This, that = That, ... }`?) What’s it useful for?

It allows reattaching the field indices with the Applicative: `(,) <$> indices <*> c`. Then using that like `indexed-traversable`.  
Or other silly things like:

```haskell
sequence_ $ attachDebugLabels <$> fmap show indices <*> textures

```

---

<div class="post-metadata">

### Author: ![mikeplus64](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/mikeplus64/32/3998_2.png) [@mikeplus64](https://discourse.haskell.org/u/mikeplus64)
#### Post date: [August 17, 2026, 5:46am UTC](https://discourse.haskell.org/t/ann-recollections-fixed-size-representable-collections/14533/4 "2026-08-17T05:46:59Z")

</div>

Rather than needing lots of TH, I’d suggest using the `Generic` to (at type-level) compute the size of the index type, and then use that along with `Enum` and `Bounded` as the basis for everything else. This is the approach I took on my previous work where I also reinvented this wheel (thinking of it more a memoisation problem than knowing about the Kmettoverse representable functors stuff 🙂) and it worked very well, something like:

```haskell
newtype Table k a = Table (SmallArray a)
  deriving stock (Functor, Foldable)

class (KnownNat (Size k)) => Tabulate k where
  type Size k :: Nat {- prior art https://stackoverflow.com/a/60169722 & finitary & probably others -}

fromFunction :: (Enum k, Bounded k, Tabulate k) => (k -> a) -> Table k a
fromFunction = createSmallArray (fromIntegral (natVal _)) (blah (universe @k))

type instance Index (Table k a) = k
type instance IxValue (Table k a) = a
instance Tabulate k => Ixed (Table k a) where
  ix k = _

```

Where a collection derived from `k` as in `recollections` is basically equivalent to a `Table k`, and instead of field accessor `_something` you use lens/optic `ix Something`. The main awkwardness of making this a package is whether you use `lens` or `optics` or `microlens` or all 3 or multiple packages… or public sublibraries… and so depending on one’s packaging decisions it becomes much ado about very little, or very little about very little :').

---

<div class="post-metadata">

### Author: ![wiz](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/wiz/32/2408_2.png) [@wiz](https://discourse.haskell.org/u/wiz)
#### Post date: [August 18, 2026, 8:19am UTC](https://discourse.haskell.org/t/ann-recollections-fixed-size-representable-collections/14533/5 "2026-08-18T08:19:51Z")

</div>

How would the `Things` example look like with this approach?  
TBH it’s not obvious what is the gain here over TH.

---

<div class="post-metadata">

### Author: ![Execute](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/execute/32/5735_2.png) [@Execute](https://discourse.haskell.org/u/Execute)
#### Post date: [August 24, 2026, 9:23am UTC](https://discourse.haskell.org/t/ann-recollections-fixed-size-representable-collections/14533/6 "2026-08-24T09:23:47Z")

</div>

Im gonna keep manually spelling them out hehehehehehe
