type5 is much more first principles based, so we get a lot of weird quirks removed: - FromLiteral no longer needs to understand AST - Type unifications works more like Haskell - Function types are just ordinary types, saving a lot of manual busywork and more.
42 lines
1.2 KiB
Python
42 lines
1.2 KiB
Python
"""
|
|
Some expression have constraints - those are usually the outmost expressions.
|
|
"""
|
|
from dataclasses import dataclass
|
|
from typing import Callable, Self
|
|
|
|
from .kindexpr import KindExpr
|
|
from .typeexpr import TypeExpr, TypeVariable, instantiate
|
|
|
|
|
|
class TypeConstraint:
|
|
"""
|
|
Base class for type contraints
|
|
"""
|
|
__slots__ = ()
|
|
|
|
def __str__(self) -> str:
|
|
raise NotImplementedError
|
|
|
|
def instantiate(self, known_map: dict[TypeVariable, TypeVariable], make_variable: Callable[[KindExpr, str], TypeVariable]) -> Self:
|
|
raise NotImplementedError
|
|
|
|
@dataclass
|
|
class ConstrainedExpr:
|
|
expr: TypeExpr
|
|
constraints: tuple[TypeConstraint, ...]
|
|
|
|
def instantiate_constrained(
|
|
constrainedexpr: ConstrainedExpr,
|
|
known_map: dict[TypeVariable, TypeVariable],
|
|
make_variable: Callable[[KindExpr, str], TypeVariable],
|
|
) -> ConstrainedExpr:
|
|
"""
|
|
Instantiates a type expression and its constraints
|
|
"""
|
|
expr = instantiate(constrainedexpr.expr, known_map, make_variable)
|
|
constraints = tuple(
|
|
x.instantiate(known_map, make_variable)
|
|
for x in constrainedexpr.constraints
|
|
)
|
|
return ConstrainedExpr(expr, constraints)
|