phasm/phasm/type3/functions.py
Johan B.W. de Vries a2e1dfd799 Reworks type class instantiation
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.
2025-04-27 17:45:13 +02:00

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)