Skip to content

Instantly share code, notes, and snippets.

@lissahyacinth
Created October 18, 2021 21:17
Show Gist options
  • Save lissahyacinth/36f5e41c55c55b77bb1af2c3eafaf76e to your computer and use it in GitHub Desktop.
Save lissahyacinth/36f5e41c55c55b77bb1af2c3eafaf76e to your computer and use it in GitHub Desktop.
from typing import TypeVar, Generic, Union, Optional
from dataclasses import dataclass
from enum import Enum, auto
carrier = TypeVar('carrier')
item = TypeVar('item')
@dataclass
class List(Generic[item]):
def cata(self,a):
return a.cata(self)
@dataclass
class Nil(List[item]):
pass
@dataclass
class Cons(List[item]):
head: item
tail: List[item]
class op(Enum):
Add = auto()
Sub = auto()
Mul = auto()
def carrier(self) -> item:
match self:
case op.Add:
return 0
case op.Sub:
return 0
case op.Mul:
return 1
def eval(self, a: item, b:item) -> item:
match self:
case op.Add:
return a + b
case op.Sub:
return a - b
case op.Mul:
return a * b
@dataclass
class Functor(Generic[item, carrier]):
method: op
cons: list[item, carrier]
def ieval(xs, carrier: Optional[item] = None) -> item:
match xs:
case Nil():
return carrier
case Functor(m, Cons(h, t)):
return m.eval(
ieval(h, m.carrier()), ieval(t, m.carrier())
)
case i:
return i
def test_eval_add():
x = Functor(
op.Add,
Cons(
1,
Functor(
op.Add,
Cons(
2,
3
)
)
)
)
assert ieval(x) == 6
if __name__ == "__main__":
test_eval_add()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment