Hi all,
I’m a big fan of sum-types and pattern matching. I’m wondering how to properly “namespace” variants in a Union?
Here’s an example. This is how I do sum types today, in a way that works well with type checkers and the match statement:
from typing import Union
from dataclasses import dataclass
@dataclass
class Square:
center: tuple[float, float]
length: float
@dataclass
class Circle:
center: tuple[float, float]
radius: float
type Shape = Union[Square, Circle]
The issue is that Square is not “encapsulated” (for the lack of a better term) to Shape. This creates problems if in the same file, I have
@dataclass
class Square:
account_token: str
handle: ...
@dataclass
class Stripe:
...
type PaymentEndpoint = Union[Square, Stripe]
The second Square shadows the first Square, which means the following would not properly:
def draw(s: Shape):
match s:
case Square(center, length): # uh oh! probably not what I had in mind
...
Contrast this with Rust, where the names are encapsulated to the containing enum:
enum Shape {
Square {center: (f64, f64), length: f64},
Circle {center: (f64, f64), radius: f64}
}
enum PaymentEndpoint {
Square { token: String, handle: ...},
Stripe { ... }
}
May I ask if there is a recommended construct in Python which does something to what Rust may achieve?
Thanks!