Unions: two may have a case of one name; which name wins, as it is

A case of one name in two unions is chosen by type, then by scope, and
the manual says so in place of "cannot both have a case called Red".
Writing programs said two imports offering one name, a type among them,
resolved to the later import; a use is refused until the program says
which, except for cases of different unions.

🤖 Generated with [ECA](https://eca.dev)

Co-Authored-By: eca-agent <git@eca.dev>
This commit is contained in:
Linus Björnstam 2026-10-22 11:27:57 +02:00
parent 684745d6c0
commit 1a407720a9
2 changed files with 25 additions and 3 deletions

View file

@ -453,10 +453,32 @@ Unions can be generic. The type variables go after the type name, just like for
You never have to write these two, since the prelude already has them under the names @code{(Option %a)}, with the cases @code{None} and @code{Some}, and @code{(Result %e %a)}, with the cases @code{Err} and @code{Ok}. They are ordinary unions, and they get a section of their own further down.
Two unions can each have a case of the same name, in one module or in two. Which one a use of the name means is decided by its type: the type wanted where it is written, the type of the value a @code{match} takes apart, or the number of values it is given, when only one of the cases takes that many.
@codeblock[#:lang "bjolang"]|{
(type (: Light (Union Red Amber Green)))
(type (: Colour (Union Red Blue (: Grey int))))
(: stop (-> Light))
(defun (stop) Red) ;; a Light, because stop returns one
(: colour-name (-> Colour string))
(defun (colour-name c)
(match c
(Red "red") ;; Colour's, because c is a Colour
(Blue "blue")
((Grey n) "grey")))
(list Red Amber) ;; Lights, because Amber is
(println (: Red Colour)) ;; written out
}|
When nothing in the definition says which union is meant, a case your module declares wins over an imported one, and an imported one over the standard library's. If that does not decide it either, as for two @code{Red}s of your own in @code{(println Red)}, the compiler asks you to write the type: @code{(: Red Light)}.
A few things to know about unions:
@read-list{
- Case names share a namespace with everything else in the module, so two unions in the same module cannot both have a case called @code{Red}.
- A case cannot have the name of a record or a newtype of the same module, because those are built by their names too.
- A union case cannot have a @code{#:mutable} field.
- @code{println} on a value of your own type prints it as you would build it, for example @code{(Card (rank Queen) (suit Hearts))} or @code{(Pip 7)}. The compiler writes this for each type you declare. To print a type another way, implement @code{Displayed} (see the traits section).
}