fp/lambda question
Alex Martelli
aleax at aleax.it
Sat Apr 13 18:22:44 EDT 2002
Jozef wrote:
...
>> def relatively_prime(a, b): return gcd(a, b) == 1
>
> Thats funny, I wanted to do that but I don't know how to use filter with a
> function that takes 2 variables. E.g., to get a list if all numbers less
> than 10 relatively prime to 3, I would write
>
> filter(relatively_prime, range(1, 10)) # aaah, where does the 3 go???
filter wants a unary function, and, as you saw in Haskell, you do that by
_currying_ (Haskell Curry is the name of the mathematician who thought
that up...):
> So I learned the lambda way. I also looked at Haskell recently, and there
> (relatively_prime 3) is a valid function that takes only 1 argument, so no
Python doesn't have built-in curry, so you hack it up in any of several
ways (of which lambda one), such as a closure:
def relativelyPrimeToN(N):
def relatively_prime(x, N=N): return gcd(x, N) == 1
return relatively_prime
and then
filter(relativelyPrimeToN(3), range(1, 10))
curry itself isn't hard to write (see the Python Cookbook for various
approaches) -- e.g., with nested scopes, and only caring about
positional arguments, again as a closure:
def curry(f, *args):
def curried(*more_args): return f(*(args+more_args))
return curried
and then
filter(curry(relatively_prime, 3), range(1, 10))
> problem there. Just a thought: a nice way to get rid of lambda's and save
> a little typing would be if for example
>
> filter(is_even, alist)
> and
> filter(is_even(_), alist)
>
> meant the same thing, and in
>
> filter(relatively_prime(3, _), alist)
Not a chance, IMHO. _ is a valid Python identifier, used in the
interactive interpreter (result of the latest expression statement)
and elsewhere (e.g. the gettext module).
If "currying with different patterns of supplied/nonsupplied args"
was crucial (but Haskell doesn't have it... you have to define a
named function for that), you could, I guess, use some other
place-holder object -- but not, I think, with function-call syntax,
or you could never pass that place-holder to any function.
Something like curry(relatively_prime, 3, curry_arg) -- though
here it would have no added value wrt the simpler curry I suggest.
Alex
More information about the Python-list
mailing list