Skip to content

Instantly share code, notes, and snippets.

@christian-marie
Last active August 29, 2015 14:24
Show Gist options
  • Save christian-marie/5f49beca5c1a1d1c4c7e to your computer and use it in GitHub Desktop.
Save christian-marie/5f49beca5c1a1d1c4c7e to your computer and use it in GitHub Desktop.
from abc import ABCMeta, abstractmethod
from typing import TypeVar, Generic
T = TypeVar('T')
class IntAlg(Generic[T], metaclass=ABCMeta):
@abstractmethod
def lit(self, lit: int) -> T: pass
@abstractmethod
def add(self, e1: T, e2: T) -> T: pass
class IntAlgInt(IntAlg[int]):
def lit(self, lit: int) -> int:
return lit
def add(self, e1: int, e2: int):
return e1 + e2
class IntAlgStr(IntAlg[str]):
def lit(self, lit: int) -> str:
return str(lit)
def add(self, e1: str, e2: str):
return "(" + e1 + " + " + e2 + ")"
def expression(alg: IntAlg[T]) -> T:
return alg.add(alg.lit(1), alg.lit(2))
print(expression(IntAlgStr()))
print(expression(IntAlgInt()))
# Now we want to retroactively add bools
class IntBoolAlg(Generic[T], IntAlg[T], metaclass=ABCMeta):
@abstractmethod
def boolean(self, b: bool): pass
@abstractmethod
def iff(self, e1: T, e2: T, e3: T): pass
class IntBoolInt(IntAlgInt, IntBoolAlg[int]):
def boolean(self, b: bool):
return (1 if b else 0)
def iff(self, e1: int, e2: int, e3: int):
return e2 if e1 else e3
class IntBoolStr(IntAlgStr, IntBoolAlg[str]):
def boolean(self, b: bool):
return str(b)
def iff(self, e1: str, e2: str, e3: str):
return "if " + e1 + " then " + e2 + " else " + e3
def expression2(alg: IntBoolAlg[T]) -> T:
return alg.iff(alg.boolean(True), alg.lit(1), alg.lit(2))
print(expression2(IntBoolStr()))
print(expression2(IntBoolInt()))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment