I don't know the proper term(s) for this situation, but it seems that two tags with the same name but different payload types can't interact with each other. Is this a feature or a bug?
expect Foo == Foo # true
expect Foo(Bar) != Foo(Baz) # true, because payloads can unify to [Bar, Baz]
expect Foo(Bar) != Foo # fails type checking, so does Foo("Bar") etc
── TYPE MISMATCH in repro.roc ──────────────────────────────────────────────────
This 2nd argument to != has an unexpected type:
10│ expect Foo(Bar) != Foo
^^^
This Foo tag has the type:
[Foo]
But != needs its 2nd argument to be:
[Foo [Bar]]a
────────────────────────────────────────────────────────────────────────────────
1 error and 0 warnings found in 31 ms
The simplest workaround seems to be to wrap any incompatible payload types in arbitrary tags, like
Foo(A(123))
Foo(B("4"))
Foo(Empty)
Technically we could allow it, but seems more error prone and confusing if the same union could have Foo
and Foo a
in it.
That said, it is important to allow Foo
and Foo a
to exist in separate tag unions. Cause that can easily happen if two libraries just happen to use the same tag name.
I'm really not sure about a use case, but I do get that from a theoretical perspective it could be allowed.
this is the correct behavior
I thought through this scenario years ago and concluded it would break things if we did it the other way, although I don't remember the specific reason anymore and would have to reconstruct the reasoning :sweat_smile:
Brendan Hansknecht said:
That said, it is important to allow
Foo
andFoo a
to exist in separate tag unions.
:check:
Yup, this works - they just can't interact.
Richard Feldman said:
this is the correct behavior
Okie dokie!
JanCVanB has marked this topic as resolved.
Last updated: Jul 06 2025 at 12:14 UTC