While this is a great idea, right now the idea hasn't taken a form that we're confident enough in. To buy us a bit more time, we're removing it for now in order to release Rel8 1.0
To implement the `DBType` instance for `[]`, we wrapped the underlying Postgres array with `ROW()`. This is to allow nesting `[]` inside `[]` (Postgres treats a bare `foo[][]` as a multidimensional array).
However, instead of unconditionally wrapping the list itself with `ROW()`, we could instead wrap individual list elements. And even better, we can wrap them *conditionally*, i.e., only if they have an array type (e.g., `foo[]`). This makes our lists much closer to Postgres arrays, and eliminates the need for `Array1D`. It also means our lists can be concatenated with a bare `||` operator; no need for the flaky `(foo).f1` unwrapping step.
This `HKD` is a better fit for `Rel8` than `higgledy`'s `HKD`. In a very literal sense, this `HKD` is now a `Rel8able` (i.e., `Context -> Type`), whereas `higgledy`'s is `(Type -> Type) -> Type`. This meant we had to use hacks like `HKD a (Compose Aggregate Expr)` to get a `HKD` into the `Aggregate` context (and similarly for `Insert`). Now we can just do `HKD a Aggregate` and `HKD a Insert` like any other `Rel8able`.
Like `higgledy`'s, our `HKD` is compatible with `generic-lens`.
One feature we have that `higgledy` doesn't is the ability to support sum types. You can make a `HKD` out of an arbitrary algebraic data type (whose fields are `DBType`s).
What's still missing is constructor/deconstructor machinery, but that's nearly finished, and the underlying machinery will also be used by the `ADT` `Rel8able`.
There is actually nothing specific to `reify` in the `Generic` version of these operations, they're actually just a specific instance of a much more general `gmap` operation. This now lives in `Rel8.Generic.Map`.
Previously these were implemented with `unsafeCoerce`, which was mostly correct, but was incorrect for certain instances of `HList`. With this change, `deriving Rel8able` will now fail to type check in those instances.
This builds upon the `Rel8.Generic.Record` machinery introduced in the previous commit. It means that we can use generic implementations of the `Table`, `EqTable`, `OrdTable` and `ToExprs` for all tuple types, rendering `HPair`, `HTrio`, `HQuartet` and `HQuintet` unnecessary (this commit removes them).
The is implemented using new machinery in `Rel8.Generic.Record`, which transforms the generic representation of any type to be as if that type was a record. Numeric labels are assigned to anonymous field selectors like `_1`, `_2`, `_3` and so on.
Previous it was `((Type -> Type) -> Type) -> Constraint`. The problem is this clashes with things like `HKD` from `higgledy`. We can use GADTs and PolyKinds hacks to get around this while mostly retaining the same API. The only major difference is we use `Result` in places where we used `Identity` before.