Welcome, guest | Sign In | My Account | Store | Cart
NOTE: Recipes have moved! Please visit GitHub.com/activestate/code for the current versions.

Suppose you have a function "sum(a, b)". This class lets you do things like:

plus4 = Curry(sum, 4)
print plus4(5)
Python, 31 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
"""This class is a curry (think functional programming)."""

__docformat__ = "restructuredtext"


class Curry:

    """This class is a curry (think functional programming).

    The following attributes are used:

    f
      This is the function being curried.

    initArgs, initKargs
      These are the args and kargs to pass to ``f``.

    """

    def __init__(self, f, *initArgs, **initKargs):
        """Accept the initial arguments and the function."""
        self.f = f
        self.initArgs = initArgs
        self.initKargs = initKargs

    def __call__(self, *args, **kargs):
        """Call the function."""
        updatedArgs = self.initArgs + args
        updatedKargs = self.initKargs.copy()
        updatedKargs.update(kargs) 
        return self.f(*updatedArgs, **updatedKargs)

In Python 2.3 or greater, it's easy to get this same functionality using a lambda acting as a closure.

2 comments

Matt Good 12 years, 9 months ago  # | flag

Xoltar Toolkit. Check out the Xoltar Toolkit at http://www.xoltar.org/languages/python.html

The "functional" module has a better implementation of curry that allows you to do things like curry parameters out of order. The other methods in there are quite useful as well.

Scott David Daniels 12 years, 9 months ago  # | flag

Matches recipe 52549. Remove any explicitly named parameters. I'm not sure how this differs much from:

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52549

From the reactions I've had from that, I'd change the first few lines of each method to:

class Curry:
    def __init__(*args, **initKargs):
        self = args[0]
        self.f = args[1]
        self.initArgs = args[2:]
        ...
    def __call__(*args, **kargs):
        self = args[0]
        updatedArgs = self.initArgs + args[1:]
        ...

This allows keyword currying or providing of _all_ parameters as named parameters.

Created by Shannon -jj Behrens on Wed, 19 Jan 2005 (PSF)
Python recipes (4591)
Shannon -jj Behrens's recipes (19)

Required Modules

  • (none specified)

Other Information and Tasks