9. Enums and better match¶
Enums let you represent “one of several shapes” as a real type, and match lets you handle it exhaustively.
A small command enum¶
enum Command:
Add(int)
Remove(int)
List
Coming from Python?
Python’s Enum is mostly “named constants”. If you want variants that carry different data, Python often uses:
strings, dataclass hierarchies, or Union types.
In Incan, enum variants can carry data (like Add(int)), and match gives you an exhaustive, compiler-checked way
to handle every case.
Matching on enums¶
def run(cmd: Command) -> None:
match cmd:
Add(x) => println(f"add {x}")
Remove(x) => println(f"remove {x}")
List => println("list")
def main() -> None:
run(Command.Add(1)) # outputs: add 1
run(Command.Remove(1)) # outputs: remove 1
run(Command.List) # outputs: list
Put enum-owned behavior on the enum¶
If a helper describes the enum itself, put it inside the enum body after the variants:
enum Command:
Add(int)
Remove(int)
List
def label(self) -> str:
match self:
Command.Add(_) => return "add"
Command.Remove(_) => return "remove"
Command.List => return "list"
def default() -> Self:
return Command.List
Call instance methods on values and associated functions on the enum type:
def main() -> None:
cmd = Command.default()
println(cmd.label()) # outputs: list
Why this matters¶
Unlike a stringly-typed “command name”, enums:
- prevent typos
- make invalid states unrepresentable
- give you exhaustive
matchchecking
Try it¶
- Add a
Clearvariant and update thematchaccordingly. - Add a
Rename(str)variant and print the new name. - Add a
label(self) -> strmethod so callers do not need a separate helper.
One possible solution
enum Command:
Add(int)
Remove(int)
Rename(str)
Clear
List
def label(self) -> str:
match self:
Command.Add(_) => return "add"
Command.Remove(_) => return "remove"
Command.Rename(_) => return "rename"
Command.Clear => return "clear"
Command.List => return "list"
def run(cmd: Command) -> None:
match cmd:
Command.Add(x) => println(f"add {x}")
Command.Remove(x) => println(f"remove {x}")
Command.Rename(name) => println(f"rename {name}")
Command.Clear => println("clear")
Command.List => println("list")
Where to learn more¶
- Enums deep dive: Enums
Next¶
Back: 8. Collections and iteration
Next chapter: 10. Models vs classes