def identity(x):
return x
def cyclist(tree):
res = []
reschildren = yield res
res.extend(reschildren)
yield
def foldcyc(tree,branch=cyclist,leaf=identity,shared=identity,getchildren=iter):
mem = dict()
def _fold(tree):
if id(tree) in mem:
return shared(mem[id(tree)])
else:
try:
children = getchildren(tree)
except:
res = leaf(tree)
mem[id(tree)] = res
return res
coroutine = branch(tree)
res = coroutine.next()
mem[id(tree)] = res
reschildren = [_fold(child) for child in children]
coroutine.send(reschildren)
return res
return _fold(tree)