Currying and composition

bearophile via Digitalmars-d digitalmars-d at puremagic.com
Sun Jul 27 07:48:19 PDT 2014


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


More information about the Digitalmars-d mailing list