Better alternative for algebraic data types
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 25/100
Hướng nghiên cứu
Start by reviewing mypy's existing union narrowing, isinstance handling, and NamedTuple support to determine whether the proposed syntax and exhaustiveness checks fit the current architecture. Done would require a settled implementation plan covering subclass registration, missing-case diagnostics, and readable union names.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Many languages support algebraic data types, including Haskell, OCaml, Scala, Swift and Rust. Many programmers like them and they have some benefits over Python subclassing, which I won't discuss in detail here.
Currently we can kind of fake algebraic data types by using union types and named tuples:
class Circle:
radius: float
class Rectangle:
width: float
height: float
Shape = Union[Circle, Rectangle]
def area(s: Shape) -> float:
if isinstance(s, Circle):
result = math.pi * s.radius**2
elif isinstance(s, Rectangle):
result = s.width * s.height
return result
There are a few problems with this currently:
- If you forget to handle a case, mypy often won't complain about this. Catching these errors is often mentioned as one of the nicest things about algebraic data types.
- You need to write each item type name twice, once in the class definition and once in the union type definition. This is somewhat error-prone.
- The union type definition needs to come after the item types, which feels backwards to me. (If we fixed forward references to types in type aliases, it might help a bit.)
- Mypy doesn't keep track of the name of the union type alias internally, and in error messages it will just print out the entire union. This could be awkward since the union can have many items.
For (1), mypy could detect at least some undefined variables and recognize (some) if statements used for "pattern matching". For example, assume that we added a new shape, Triangle. Now mypy should complain about area(), as it fails to handle triangles (if we'd have used multiple returns, mypy could already have caught the error):
def area(s: Shape) -> float:
if isinstance(s, Circle):
result = math.pi * s.radius**2
elif isinstance(s, Rectangle):
result = s.width * s.height
return result # Error: "result" may be undefined (union item "Triangle" not handled)
For (2), (3) and (4), we could have some new syntax:
from mypy_extensions import NamedTupleUnion
class Shape(NamedTupleUnion): # This would be roughly similar to original union type
pass
class Circle(Shape):
radius: float
class Rectangle(Shape):
width: float
height: float
NamedTupleUnion would have a few special features. All subclasses are named tuples and must be defined in the same module as the NamedTupleUnion type (i.e. it can't be extended outside the current module). This way we can check whether all item types are handled using isinstance checks. Finally, only one level of inheritance would be supported, for simplicity -- though I'm not sure if this restriction is necessary.
[This is just a random idea I wanted to write down and it's not urgent in any way.]
- Ngôn ngữ chính
- Python
- Star
- 20.6k
- Fork
- 3.3k
- Merge trung bình
- 1 ngày 18 giờ
- Pull request đã merge (30 ngày)
- 54
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của python/mypy
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
-
documentation
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
-
bug topic-configuration topic-error-reporting
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
Issue tương tự
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 90/100
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
zostera/django-bootstrap4#894 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
use-agent-os/agent-os#3276 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
zephyrproject-rtos/zephyr#119726 ·
-
area/auth bug comp/agent P3 platform/discord type/security
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
NousResearch/hermes-agent#117848 ·