Simon Alford
Simon Alford

Reputation: 2643

Python curried function with variable number of arguments

Given n, I'd like to make a function which takes in n elements and returns them as a list. One way to do this:

def g(n):
  def f(*l):
    assert len(l) == n
    return l
  return f

My problem: I'd like the return function to be curried.

The result would work something like this, but for all n:

def g(n):
    if n == 1: return lambda i: [i]
    if n == 2: return lambda i1: lambda i2: [i1, i2]
    if n == 3: return lambda i1: lambda i2: lambda i3: [i1, i2, i3]
    ...

My first approach went something like this:

def g(n):
    if n == 1: return lambda i: [i]
    return lambda i: g(n-1) + [i]

This doesn't work: g(n-1) returns a function, so it can't be added to the list. Is there a fix?

It seems like I need to somehow "pass the input" along to g(n-1), get the output of g(n-1), and tack on [i], but I don't know how to "pry open" g(n-1) to do the tacking on, while maintaining the correct input type for it.

I tried googling currying in python, but I only got some basic examples. I am new to functional programming, so sorry if my terminology is lacking.

Upvotes: 2

Views: 449

Answers (1)

Niklas Mohrin
Niklas Mohrin

Reputation: 1928

I came up with this:

def f(n, prev=None):
    if prev is None:
        prev = []

    if n == 1:
        return lambda x: prev + [x]
    else:
        return lambda x: f(n-1, prev=prev + [x])

# f(3) creates list with length 3
# other calls append one element to the list, until length 3 is reached
assert f(3)(1)(2)(3) == [1,2,3]

Upvotes: 3

Related Questions