You could also define an internal auxiliary function (loop
) which keeps track of the sum state (acc
) as the counter state (n
) decrements
def multiadder(n):
def loop(acc,n):
if n == 0:
return acc
else:
return lambda x: loop(acc+x, n-1)
return loop(0,n)
print(multiadder(3)(1)(2)(3)) # 6
print(multiadder(5)(1)(2)(3)(4)(5)) # 15
It's not nearly as elegant as DarkKnight's answer, but it might be easier for a beginner to conceptualize. In fact, this pattern is so useful and versatile that I use it to define almost all of my recursive procedures.
def some_recursive_func:
def loop(...state_parameters):
if base_condition:
return answer
else:
return loop(...updated_state_variables)
return loop(...initial_state_variables)
The only adaptation we made to this pattern is wrapping the recursive branch of the if
expression in in lambda x: ...
– this is because multiadd
is meant to return functions until n
returned functions have been applied.
One more, just for fun using the legendary Y-combinator. This probably doesn't meet the criteria provided by your instructor, but it's cool to see it nonetheless. Multiline lambdas in python are not really a thing so readability suffers a little bit.
U = lambda f: f(f)
Y = U (lambda h: lambda f: f (lambda x: h (h) (f) (x)))
multiadder = Y (lambda f: lambda acc: lambda n:
acc if n == 0 else lambda x: f (acc+x) (n-1)
) (0)
print(multiadder(3)(1)(2)(3)) # 6
print(multiadder(5)(1)(2)(3)(4)(5)) # 15
Or you could still have defined multiadder
using def
syntax if you wanted
def multiadder(n):
return Y (lambda f: lambda acc: lambda n:
acc if n == 0 else lambda x: f (acc+x) (n-1)
) (0) (n)
It works the same way.
I highly encourage you to trace the evaluation step-by-step to understand how it works. There are some tremendous insights to be gained in understanding these higher-order functions.