I'm working on a Tailwind-like styling system. The plan is to map to tags margin-2 -> Margin(All, 2), rounded-tl-lg -> Rounded(Tl, Lg) to allow for component tree serialization. Then there'd be a registry of tag handlers that matches the tag and passes the associated data into the handler and the handler does the work to actually make it happen.
I'd like for the tag union to be open but there doesn't seem to be a way to get at the tag or contents in the fallback handler. Did I miss something? Is my design intent off?
You cannot know the shape of the fallback tag union, that's why it's a fallback. It might be a single payload thing or have 10 different kinds of payloads all with different representation at the hardware level. If you want a "fallback" tag, you should manually define that, kinda like how the Rust std::io::EfforKind has an Other enum variant. For the fallback case, you would probably use a default value (since you want an open union I assume returning an error is not your goal)
I appreciate the response. I'm used to GC language making shapes a non-concern.
You're welcome! Open tag unions are weird. They don't really map to oop concepts (if that's your bckground). They aren't the generic object you can defult to. They are used mostly as either an intermediate type to build up a closed union or as an API contract that says "I want to be able to add more variants to this union later without breaking you usage code, so you have to assume there's always a case you're not handling ". There's not really anything you can "do" with the fallback variant, except pass it through or discard.
My only other experience with them is in OCaml and I didn't spend that much time with the language.
you have more experience than me then :D
I was vaguely assuming I could have a list, use the tag id for the lookup and vaguely pass the rest through.
I wonder if it'd be theoretically possible to match you own module's tags on an open union without running into coherence issues. Like it'd match on the closed list and then on the extended closed list and then hit the fallback.
It'd be useful here but I don't know how useful it'd be in general. Aside from monkeypatching in dynamic languages, my only experience with being able to re-open more or less anything is with Clojure's protocols which are basically Rust traits where being able to arbitrarily map somet random Java object type to a particular protocol was periodically useful.
I don't know if it's that useful, but perhaps you could store the string version/some other generic but common representation before parsing alongside? Otherwise I think once it has been parsed into a tag but then effectively discarded into the open part of the union there's not much you can do?
That is, if it's for something like handling unknown cases
Ah my bad, I realise Norbert covered that already
Last updated: Jul 23 2026 at 13:15 UTC