Skip to content

Instantly share code, notes, and snippets.

@jorenham
Created March 22, 2024 02:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jorenham/6bba7c5a749759922e278cdd5d1b6d45 to your computer and use it in GitHub Desktop.
Save jorenham/6bba7c5a749759922e278cdd5d1b6d45 to your computer and use it in GitHub Desktop.
Emulating integer in Python's type system: addition and subtraction
from __future__ import annotations
from typing import Protocol
class _Int(Protocol):
def __int__(self) -> int: ...
def __pos__(self) -> _Int: ...
def __neg__(self) -> _Int: ...
class O:
__match_args__ = ()
def __int__(self) -> int:
return 0
def __pos__(self) -> P[O]:
return P(self)
def __neg__(self) -> N[O]:
return N(self)
class _XNum[X: _Int]:
__match_args__ = ('x',)
x: X
def __init__(self, x: X, /):
self.x = x
class P[X: _Int](_XNum[X]):
def __int__(self) -> int:
return int(self.x) + 1
def __pos__(self: P[X]) -> P[P[X]]:
return P(self)
def __neg__(self) -> X:
return self.x
class N[X: _Int](_XNum[X]):
def __int__(self) -> int:
return int(self.x) - 1
def __pos__(self) -> X:
return self.x
def __neg__(self: N[X]) -> N[N[X]]:
return N(self)
o = O()
reveal_type(++o) # Type of "++o" is "P[P[O]]"
reveal_type(--o) # Type of "--o" is "N[N[O]]"
reveal_type(+-o) # Type of "+-o" is "O"
reveal_type(-+o) # Type of "-+o" is "O"
reveal_type(++-+++-+-o) # Type of "++-+++-+-o" is "P[P[P[O]]]"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment