Skip to content

Parameterize ADT tag types - #424

Open
dathegreat wants to merge 1 commit into
circuithub:masterfrom
dathegreat:master
Open

dathegreat wants to merge 1 commit into
circuithub:masterfrom
dathegreat:master

Conversation

@dathegreat

Copy link
Copy Markdown

Hello maintainers! May I please get your thoughts on this feature before I spend time writing more haddock documentation for it? Are you interested in adding this functionality to Rel8?

Motivation

I ran into a scenario at my day job where I needed to encode an ADT in one of our tables. Because I generally prefer encoding database constraints at the type level if possible, I wanted to make the tag column a Postgres enum, rather than a text type. I also read #422 the other day, and thought this could be an interesting step in that direction as well (using something like ADTWith NoTag t, maybe?)

AI Disclaimer

I used an LLM to assist with these changes. On a scale from vibe-code slop to 100% handwritten research paper, I would give this a 7/10.

Added

  • An ADTWith tag t type which generalizes the ADT type's hardcoded text
    tag column, so the tag can be any type, such as a PostgreSQL enum.
  • An ADTTag class to define tag types. A tag type must be a NonNull DBType
    with Eq and DBEq, whose constructors are all nullary (zero parameters) and
    correspond one-to-one with the ADT's constructors. This tag <-> ADT bijection
    is defined by ADTTag's associated TagConstructor type. Mismatches are
    reported as type errors.
  • Generalized ...With versions of the existing ADT types and functions, such
    as HADTWith, NameADTWith/nameADTWith, buildADTWith and
    constructADTWith.

Changed

  • ADT, HADT, ADTable, BuildableADT, ConstructableADT, NameADT, etc.
    are now synonyms for their ...With versions applied to Tag, such as
    type ADT = ADTWith Tag. Functions like buildADT delegate similarly to
    their ...With versions. Existing code using them is unaffected, apart from
    the following.
  • Breaking: Because ADT is now a type synonym, instances on it such as
    instance C (ADT t) require FlexibleInstances. This is enabled by default
    in GHC2021.

@coderabbitai

coderabbitai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: 2c653e7c-c0dc-4a9d-a946-872c2df02249
Commits

Reviewing files that changed from the base of the PR and between 7f28803 and 066258a.

Files selected for processing: 1
  • rel8/src/Rel8.hs
Files skipped from review as they are similar to previous changes: 1
  • rel8/src/Rel8.hs

Included review availability: This review used your included allowance. 3 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour.

Walkthrough

The change adds custom tag types for ADTs and threads them through generic serialization, construction, deconstruction, and naming. Existing APIs specialize to Tag. Tests cover enum-backed tags, nested ADTs, and compile-time tag validation.

Changes: Custom-tag ADTs

Layer / File(s) Summary
Tag contracts and validation
rel8-internal/src/Rel8/Internal/Type/Tag.hs, rel8-internal/src/Rel8/Internal/Generic/Table/ADT.hs, rel8-internal/src/Rel8/Internal/Generic/Table/ADT/Tag.hs
ADTTag defines tag constraints and constructor mappings. Compile-time checks validate constructor counts, nullary tag constructors, and unique mappings. Helpers create and inspect tag columns.
Tag-aware ADT serialization
rel8-internal/src/Rel8/Internal/Generic/Table.hs, rel8-internal/src/Rel8/Internal/Generic/Table/ADT.hs
Generic ADT columns and serialization now carry a tag type. Serialization and result conversion use tag values and tests.
Tag-aware construction and deconstruction
rel8-internal/src/Rel8/Internal/Generic/Construction.hs, rel8-internal/src/Rel8/Internal/Generic/Construction/ADT.hs
Generic build, construction, deconstruction, and naming operations carry the tag type. Constructor matching uses tag-column expressions and tag mappings.
Public API and default-tag integration
rel8-internal/src/Rel8/Internal/Table/ADT.hs, rel8-internal/src/Rel8/Internal/Column/ADT.hs, rel8-internal/src/Rel8/Internal/Table/HKD.hs, rel8-internal/src/Rel8/Internal/Table/Rel8able.hs, rel8/src/Rel8.hs, rel8-internal/rel8-internal.cabal, changelog.d/20261022_000000_dmarcyes_adt_enum_tag.md
Rel8 exports ADTWith, HADTWith, and the custom-tag APIs. Existing ADT APIs specialize to Tag. HKD and Rel8able integrations pass tag types through generic operations.
Custom-tag test coverage
rel8/tests/Rel8/ADTWith/Test.hs, rel8/tests/Main.hs, rel8/tests/type-errors/ADTTag.hs, rel8/rel8.cabal
Tests cover enum-backed tags, constructor mappings, build and construction operations, nested ADTs, and compile-time validation failures.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant buildADTWith
  participant ggbuild
  participant gmakeADT
  participant gtagExpr
  Caller->>buildADTWith: request constructor build
  buildADTWith->>ggbuild: pass tag-indexed columns
  ggbuild->>gmakeADT: pass constructor name and fields
  gmakeADT->>gtagExpr: obtain constructor tag expression
  gtagExpr-->>gmakeADT: return tag expression
  gmakeADT-->>Caller: return tagged ADT expression
Loading

Suggested reviewers: chrisdone-artificial

Merge Risk: Minimal · up to 06625

The custom-tag documentation concern is addressed. No remaining issue in the supplied review evidence prevents merge.

Pre-merge checks: Passed 5
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: parameterizing ADT tag types.
Description check Passed The description directly explains the new ADTWith and ADTTag functionality, generalized APIs, compatibility impact, motivation, and testing-related considerations.
Docstring Coverage Passed No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 0 files. (1 skipped: 1 unsupported.)

Finishing Touches
Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

A rabbit checks each tag in place
Then hops through schemas at a pace
Enum leaves mark each constructor’s trail
Round trips return with every detail
The burrow’s types all match today

@dathegreat
dathegreat marked this pull request as ready for review November 2, 2026 17:07

@coderabbitai coderabbitai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Fix comments: Fix CodeRabbit comments on this PR

Comment thread rel8/src/Rel8.hs Resolved
@dathegreat

Copy link
Copy Markdown
Author

@TeofilC I am curious to hear your opinion, when you have the time, especially if you think this is a viable path toward #422
or not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant