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