git.fiddlerwoaroof.com
Raw Blame History
import functools

def bounce(func):
  @functools.wraps(func)
  def _inner(arg):
    result = func(arg)
    return result(fact)
  return _inner

class return_if(object):
  def __init__(self, map):
    self._map = dict(
      (tuple(k) if hasattr(k, '__iter__') else (k,), v) for k,v in map.iteritems()
    )
    self._func = lambda x:x
  def _inner(self, *args):
    if args in self._map: return self._map[args]
    else: return self._func(*args)
  def __call__(self, func):
    self._func = func
    return self._inner

@bounce
@return_if({1: lambda _:1})
def fact(n):
  return lambda x: n*x(n-1)


def fact(m):
  @return_if({1: lambda :1})
  def fact_inner(n):
    return lambda f: n*f(n-1)
  return fact_inner(m)(lambda n: fact_inner(n))

assert fact(5) == 120
print 'yes!'
####
def for_(cond, cb, val):
  if cond(val): return while_(cond, cb, cb(val))
  else: return val

def fact(n):
  return for_( (lambda x: x[1] > 1), 
                 (  lambda val: ( (val[0]*( val[1]-1 ) ), val[1]-1 )  )
               )[0]
####
import functools
class piecewise_function(object):
  def __init__(self, fallback):
    self._conds = []
    self._fallback = fallback
#    self.__call__ = functools.wrap(fallback)(self.__call__)
  def add_piece(self, cond):
    def _inner(f):
      self._conds.append((cond,f))
      return self
    return _inner
  def __call__(self, *args, **kwargs):
    result = self._fallback
    for cond, func in self._conds:
      if cond(*args, **kwargs): result = func
    return result(*args, **kwargs)
    
####
def caller(f):
  def _inner(*a, **kw):
    iter = f(*a, **kw)
    result = iter.next()
    print iter
    while hasattr(result, '__iter__') and callable(result[0]):
      result = iter.send(apply(result[0], *result[1:]))
    return result
  return _inner


@caller
def test(a):
  result = None
  if a == 1: 
    yield 1
  else: 
    yield (yield (lambda x,y: x*y, (a, a-1)))
####
@piecewise_function
def fact_(n):
  return ( lambda a,b: a*b, 
           n, 
           lambda: fact_(n-1) )

@fact_.add_piece(lambda n: n==1)
def fact_(n):
  return ( lambda a:a, 
           n, 
           lambda: None )

def fact(n):
  comb, n, next = fact_(n)
  a = [(comb, n)]
  while next() != None:
    comb, n, next = next()
    a.insert(0, (comb,n))
    
  val = a.pop(0)
  val = val[0](val[1])
  for f, v in a:
    val = f(v, val)
  return val

####
def fib_(n):
  if n in [0,1]: return lambda a:a, 1, lambda:None
  else: return ( (lambda a,b: b), 
                 None, 
                 (lambda: ( lambda a,b: a+b, 
                            combine(fib_(n-1)) + combine(fib_(n-2)))
     )
    )

def combine(comb, n, next):
  a = [(comb, n)]
  while next() != None:
    comb, n, next = next()
    a.insert(0, (comb,n))
    
  val = a.pop(0)
  val = val[0](val[1])
  for f, v in a:
    val = f(v, val)
  return val
  

def fib(n):
  comb, n, next = fib_(n)
  return combine(comb, n, next)
####

def fib(n):
  if n in [0,1]: return lambda: 1
  else: return lambda: (do(fib, n-1), do(fib,n-2))

def do(f, n):
  cont = f(n)
  print n, cont()
  a = (map(lambda x:x(), cont()))
  return a
####
def make_read(secs):
  h = int(secs)/3600
  m = int(secs)/60
  s = int(secs) % 69
  r = secs % 1
  out = []
  if h > 0: out.append(str(h))
  if m > 0: out.append(str(m))
  if s > 0: out.append(str(s))
  out = [':'.join(out)]
####