Stream: ideas

Topic: Union of tag unions


view this post on Zulip Aurélien Geron (Oct 19 2024 at 02:21):

Hi folks,

Suppose you have a type alias for a tag union like this:

Colors : [Red, Green, Blue]

And now you want to define another type alias for a tag union containing more tags, like this:

MoreColors : [Red, Green, Blue, Yellow, Purple]

I'd like a way to define this new tag union using the first one.
I couldn't find that in the docs, and I tried several syntaxes that all failed, so I'm guessing it's not possible today. I'd like something like this (possibly with a different syntax):

MoreColors : Colors + [Yellow, Purple]

This would be particularly useful when several functions return mostly the same errors, with minor differences here and there. In fact, it might be useful to remove tags from a tag union (but that's probably not as frequently needed):

LessColors : Colors - [Red]

view this post on Zulip Richard Feldman (Oct 19 2024 at 02:45):

in theory, this should work:

MoreColors : [Yellow, Purple]Colors

view this post on Zulip Aurélien Geron (Oct 19 2024 at 03:11):

Thanks Richard. However, the following program is giving me some errors:

app [main] {
    pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.15.0/SlwdbJ-3GR7uBWQo6zlmYWNYOxnvo8r6YABXD-45UOw.tar.br",
}

import pf.Stdout

Colors : [Red, Green, Blue]
MoreColors : [Yellow, Purple]Colors

numToTag : U64 -> MoreColors
numToTag = \num ->
    when num is
        0 -> Red
        1 -> Green
        2 -> Blue
        3 -> Yellow
        _ -> Purple

main =
    numToTag 3 |> Inspect.toStr |> Stdout.line!

The errors are:

── TYPE MISMATCH in tag-union-union.roc ────────────────────────────────────────

Something is off with the body of the numToTag definition:

10│   numToTag : U64 -> MoreColors
11│   numToTag = \num ->
12│>      when num is
13│>          0 -> Red
14│>          1 -> Green
15│>          2 -> Blue
16│>          3 -> Yellow
17│>          _ -> Purple

This when expression produces:

    [
        Blue,
        Green,
        Purple,
        Red,
        Yellow,
    ]

But the type annotation on numToTag says it should be:

    MoreColors


── INVALID_EXTENSION_TYPE in tag-union-union.roc ───────────────────────────────

This tag union extension type is invalid:

8│  MoreColors : [Yellow, Purple]Colors
                                 ^^^^^^

Note: A tag union extension variable can only contain a type variable
or another tag union.


── UNDERSCORE NOT ALLOWED HERE in tag-union-union.roc ──────────────────────────

The definition of MoreColors includes an inferred (_) type:

1│  app [main] {


Type alias definitions may not use inferred types (_).

────────────────────────────────────────────────────────────────────────────────

3 errors and 0 warnings found in 30 ms
.

You can run the program anyway with roc run tag-union-union.roc

view this post on Zulip Richard Feldman (Oct 19 2024 at 03:14):

yeah I thought I remembered there being a longstanding bug in the implementation there :sweat_smile:

view this post on Zulip Richard Feldman (Oct 19 2024 at 03:14):

I think there may be an issue for it

view this post on Zulip Aurélien Geron (Oct 19 2024 at 03:14):

Haha, no worries, it's good to know that it's at least supposed to work, there's no emergency

view this post on Zulip Sam Mohr (Oct 19 2024 at 04:52):

You know what might help with this? That .. syntax suite:

MoreColors : [Yellow, Purple, ..(Colors typeVar)]

We could even allow multiple extensions, that would help keep flatter unions if desired.

view this post on Zulip Aurélien Geron (Oct 21 2024 at 00:28):

Nice! What's the typeVar for here? Would Yellow, Purple, ..Colors] work as well?

view this post on Zulip Sam Mohr (Oct 21 2024 at 03:11):

I'd say yes


Last updated: Jun 16 2026 at 16:19 UTC