Currying and composition
Matt Soucy via Digitalmars-d
digitalmars-d at puremagic.com
Sun Jul 27 08:42:35 PDT 2014
On 07/27/2014 10:48 AM, bearophile wrote:
> In std.functional there is a curry(), that looks more like a partial application.
>
> In the Python land I've recently seen a library for a more functional style of coding:
> https://pypi.python.org/pypi/PyMonad/
>
> I don't like for Python most of the stuff in that PyMonad library, but two bits look nice. I quote them here:
>
> <<
>
> @curry
> def add(x, y):
> return x + y
>
> @curry
> def func(x, y, z):
> # Do something with x, y and z.
> ...
>
> The above fuctions can be partially applied by passing them less than their full set of arguments:
>
> add(7, 8) # Calling 'add' normally returns 15 as expected.
> add7 = add(7) # Partial application: 'add7' is a function taking one argument.
> add7(8) # Applying the final argument retruns 15...
> add7(400) # ... or 407, or whatever.
>
> # 'func' can be applied in any of the following ways.
> func(1, 2, 3) # Call func normally.
> func(1, 2)(3) # Partially applying two, then applying the last argument.
> func(1)(2, 3) # Partially applying one, then applying the last two arguments.
> func(1)(2)(3) # Partially applying one, partially applying again, then applying the l
>
>
>
> Curried functions can be composed with the * operator. Functions are applied from right to left:
>
> # Returns the first element of a list.
> @curry
> def head(aList):
> return aList[0]
>
> # Returns everything except the first element of the list.
> @curry
> def tail(aList):
> return aList[1:]
>
> second = head * tail # 'tail' will be applied first, then its result passed to 'head'
> second([1, 2, 3, 4]) # returns 2
>
>
> You can also compose partially applied functions:
>
> @curry
> def add(x, y):
> return x + y
>
> @curry
> def mul(x, y):
> return x * y
>
> comp = add(7) * mul(2) # 'mul(2)' is evaluated first, and it's result passed to 'add(7)'
> comp(4) # returns 15
>
>>>
>
>
> Perhaps I'd like in Phobos a "curry" (or another name) template that returns a callable struct that allows both those operations: the currying with arbitrary partial application and the "*" operator to perform function composition (I think the two pieces of functionality go well together despite being different things, because they are both used in a very functional style of coding).
>
> Bye,
> bearophile
So, in the next release std.functional.curry has been renamed to std.functional.partial:
https://github.com/D-Programming-Language/phobos/pull/1979
I was starting to work on a proper curry replacement, but due to some real-life stuff I haven't had time.
There's some starting code at https://issues.dlang.org/show_bug.cgi?id=4391 that I was basing mine off of, but I was running into some issues involving static, and a ton of issues with templated functions. This might be something worth looking into?
--
Matt Soucy
http://msoucy.me/
--
Matt Soucy
http://msoucy.me/
More information about the Digitalmars-d
mailing list