Skip to content

Instantly share code, notes, and snippets.

@qexat
Created September 26, 2025 07:21
Show Gist options
  • Select an option

  • Save qexat/9f81b4becd80e92e7485bb6d3f5704c7 to your computer and use it in GitHub Desktop.

Select an option

Save qexat/9f81b4becd80e92e7485bb6d3f5704c7 to your computer and use it in GitHub Desktop.
static verification of equality in python! try it on a typechecker like pyright
from __future__ import annotations
import abc
import dataclasses
import typing
type Nat = Zero | Succ[Nat]
@dataclasses.dataclass(slots=True, frozen=True)
@typing.final
class Zero:
pass
@dataclasses.dataclass(slots=True, frozen=True)
@typing.final
class Succ[N: Nat]:
n: Nat
class Eq[T, U](abc.ABC):
@abc.abstractmethod
def __new__(cls, x: T) -> Eq[T, T]:
pass
@staticmethod
def refl(n: T) -> Eq[T, T]:
return Refl(n)
@typing.final
class Refl[T](Eq[T, T]):
__match_args__ = ("x",)
@typing.override
def __new__(cls, x: T) -> Eq[T, T]:
return super().__new__(cls, x)
def __init__(self, x: T) -> None:
self._x: typing.Final = x
type Two = Succ[Succ[Zero]]
type Three = Succ[Two]
two: Two = Succ(Succ(Zero()))
three: Three = Succ(Succ(Succ(Zero())))
good_eq_two_two: Eq[Two, Two] = Refl(two)
bad_refl_two: Eq[Two, Three] = Refl(two)
bad_refl_three: Eq[Two, Three] = Refl(three)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment