Before, a type class was a property of a type. But that doesn't make any sense for multi parameter type classes. Had to make a hacky way for type classes with type constructors.
79 lines
2.3 KiB
Python
79 lines
2.3 KiB
Python
from typing import TYPE_CHECKING, Any, Iterable, List, Union
|
|
|
|
if TYPE_CHECKING:
|
|
from .typeclasses import Type3Class
|
|
from .types import Type3
|
|
|
|
|
|
class TypeVariable:
|
|
"""
|
|
Types variable are used in function definition.
|
|
|
|
They are used in places where you don't know the exact type.
|
|
They are different from PlaceholderForType, as those are instanced
|
|
during type checking. These type variables are used solely in the
|
|
function's definition
|
|
"""
|
|
__slots__ = ('letter', )
|
|
|
|
letter: str
|
|
|
|
def __init__(self, letter: str) -> None:
|
|
assert len(letter) == 1, f'{letter} is not a valid type variable'
|
|
self.letter = letter
|
|
|
|
def __hash__(self) -> int:
|
|
return hash(self.letter)
|
|
|
|
def __eq__(self, other: Any) -> bool:
|
|
if not isinstance(other, TypeVariable):
|
|
raise NotImplementedError
|
|
|
|
return self.letter == other.letter
|
|
|
|
def __repr__(self) -> str:
|
|
return f'TypeVariable({repr(self.letter)})'
|
|
|
|
class ConstraintBase:
|
|
__slots__ = ()
|
|
|
|
class Constraint_TypeClassInstanceExists(ConstraintBase):
|
|
__slots__ = ('type_class3', 'types', )
|
|
|
|
type_class3: 'Type3Class'
|
|
types: list[TypeVariable]
|
|
|
|
def __init__(self, type_class3: 'Type3Class', types: Iterable[TypeVariable]) -> None:
|
|
self.type_class3 = type_class3
|
|
self.types = list(types)
|
|
|
|
# Sanity check. AFAIK, if you have a multi-parameter type class,
|
|
# you can only add a constraint by supplying types for all variables
|
|
assert len(self.type_class3.args) == len(self.types)
|
|
|
|
class TypeVariableContext:
|
|
__slots__ = ('variables', 'constraints', )
|
|
|
|
variables: set[TypeVariable]
|
|
constraints: list[ConstraintBase]
|
|
|
|
def __init__(self) -> None:
|
|
self.variables = set()
|
|
self.constraints = []
|
|
|
|
def __copy__(self) -> 'TypeVariableContext':
|
|
result = TypeVariableContext()
|
|
result.variables.update(self.variables)
|
|
result.constraints.extend(self.constraints)
|
|
return result
|
|
|
|
class FunctionSignature:
|
|
__slots__ = ('context', 'args', )
|
|
|
|
context: TypeVariableContext
|
|
args: List[Union['Type3', TypeVariable]]
|
|
|
|
def __init__(self, context: TypeVariableContext, args: Iterable[Union['Type3', TypeVariable]]) -> None:
|
|
self.context = context.__copy__()
|
|
self.args = list(args)
|