Skip to content

Instantly share code, notes, and snippets.

@Kraks
Last active September 12, 2018 04:33
Show Gist options
  • Save Kraks/7b9d358bd3b8770c61a08632a22b2fa2 to your computer and use it in GitHub Desktop.
Save Kraks/7b9d358bd3b8770c61a08632a22b2fa2 to your computer and use it in GitHub Desktop.
class Shift:
def __init__(self, fun):
self.fun = fun
def map(self, f): return Shift(lambda k: self.fun(lambda x: k(f(x))))
def bind(self, f): return Shift(lambda k: self.fun(lambda x: f(x).fun(k)))
def bind2(self, f):
def aux(k):
def aux1(x):
fx = f(x)
if isinstance(fx, Shift): return fx.fun(k)
return k(fx)
return aux1
return Shift(lambda k: self.fun(aux(k)))
def reset(c): return c.fun(lambda x: x)
if __name__ == "__main__":
ctx = Shift(lambda k: k(k(k(7)))).bind2(lambda x: x+1)
assert(reset(ctx) == 10)
ctx = Shift(lambda k: k(7)).bind2(lambda x: x+1)
assert(reset(ctx) * 2 == 16)
def f(k):
k(k(k(7)))
return "done"
ctx = Shift(f).bind2(lambda x: x+1)
assert(reset(ctx) == "done")
ctx = Shift(lambda k: k(k(k(7)))).bind2(lambda x: x+1)
assert(reset(ctx) * 2 == 20)
def foo(): return Shift(lambda k: k(k(k(7)))).bind2(lambda x: x+1)
def bar(): return foo().bind2(lambda x: x*2)
def baz(): return reset(bar())
assert(baz() == 70) # 70
def foo1(): return Shift(lambda k: k(k(k(7)))).bind2(lambda x: x+1)
def bar1(): return foo1().bind2(lambda x: Shift(lambda k: k(7)).bind2(lambda y: x+y))
def baz1(): return reset(bar1())
assert(baz1() == 31) # 31
def foo2(): return Shift(lambda k: k(k(7))).bind2(lambda x: x+1)
def bar2(): return foo2().bind2(lambda x: foo2().bind2(lambda y: x+y))
def baz2(): return reset(bar2())
assert(baz2() == 61) # 61
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment