Is there an exact replacement for the old functionality.

I am trying to run this snippet from http://www.ibm.com/developerworks/linux/library/l-prog3.html in python 2.6 runtime.

from functional import * taxcalc = lambda income,rate,deduct: (income-(deduct))*rate taxCurry = curry(taxcalc) taxCurry = taxCurry(50000) taxCurry = taxCurry(0.30) taxCurry = taxCurry(10000) print "Curried taxes due =",taxCurry print "Curried expression taxes due =", \ curry(taxcalc)(50000)(0.30)(10000) 

Well, that’s why I understand from http://www.python.org/dev/peps/pep-0309/ that the functionality is renamed to functools and curry to partial, but just doing the renaming does not help, I get an error message:

 taxCurry = taxCurry(50000) TypeError: <lambda>() takes exactly 3 arguments (1 given) 

The following works, but do I really need to change it so much?

 from functools import partial taxcalc = lambda income,rate,deduct: (income-(deduct))*rate taxCurry = partial(taxcalc) taxCurry = partial(taxCurry, 50000) taxCurry = partial(taxCurry, 0.30) taxCurry = partial(taxCurry, 10000) print "Curried taxes due =", taxCurry() print "Curried expression taxes due =", \ taxcalc(50000, 0.30, 10000) 

Is there a better way to keep the mechanics of the original example? After all, was the original example really currying or just a partial application? (according to http://www.uncarved.com/blog/not_currying.mrk )

thank you for your time

+4
source share
3 answers

I guess why they changed this because Python is dynamically typed. This means that it would be very difficult to debug the curry source if something goes wrong - much more complicated than in a language like Haskell, where you will immediately get a good type error. Therefore, I believe that a reasonable solution is to replace it with a more explicit version of partial (looks more pythonic for me).

Your example is also a bit strange, as you simply reassign partially applied functions with the same name. A commonly used function should be assigned to another function. At least this is the only reasonable use case in Python that I can think of.

+2
source

The curry implementation in the toolz project should be a replacement.

 $ pip install toolz >>> from toolz import curry 
+1
source

I wrote a curry decorator implementation that works well:

 def curry(func): """ Decorator to curry a function, typical usage: >>> @curry ... def foo(a, b, c): ... return a + b + c The function still work normally: >>> foo(1, 2, 3) 6 And in various curried forms: >>> foo(1)(2, 3) 6 >>> foo(1)(2)(3) 6 This also work with named arguments: >>> foo(a=1)(b=2)(c=3) 6 >>> foo(b=1)(c=2)(a=3) 6 >>> foo(a=1, b=2)(c=3) 6 >>> foo(a=1)(b=2, c=3) 6 And you may also change your mind on named arguments, But I don't know why you may want to do that: >>> foo(a=1, b=0)(b=2, c=3) 6 Finally, if you give more parameters than expected, the exception is the expected one, not some garbage produced by the currying mechanism: >>> foo(1, 2)(3, 4) Traceback (most recent call last): ... TypeError: foo() takes exactly 3 arguments (4 given) """ def curried(*args, **kwargs): if len(args) + len(kwargs) >= func.__code__.co_argcount: return func(*args, **kwargs) return (lambda *args2, **kwargs2: curried(*(args + args2), **dict(kwargs, **kwargs2))) return curried if __name__ == "__main__": import doctest doctest.testmod() 
-1
source

Source: https://habr.com/ru/post/1340508/


All Articles