Partial function application
Partial function application is the ability to take a function of many parameters and apply arguments to some of the parameters to create a new function that needs only the application of the remaining arguments to produce the equivalent of applying all arguments to the original function.
E.g:
- Given values
v1, v2
- Given
f(param1, param2)
- Then
partial(f, param1=v1)
returnsf'(param2)
- And
f(param1=v1, param2=v2) == f'(param2=v2)
(for any value v2)
- Task
- Create a function fs( f, s ) that takes a function, f( n ), of one value and a sequence of values s.
Function fs should return an ordered sequence of the result of applying function f to every value of s in turn.
- Create function f1 that takes a value and retuns it multiplied by 2.
- Create function f2 that takes a value and returns it squared.
- Partially apply f1 to fs to form function fsf1( s )
- Partially apply f2 to fs to form function fsf2( s )
- Test fsf1 and fsf2 by evaluating them with s being the sequence of integers from 0 to 3 inclusive and then the sequence of even integers from 2 to 8 inclusive.
Python
<lang python>from functools import partial
def fs(f, s): return [f(value) for value in s]
def f1(value): return value * 2
def f2(value): return value ** 2
fsf1 = partial(fs, f1) fsf2 = partial(fs, f2)
s = [0, 1, 2, 3] assert fs(f1, s) == fsf1(s) # == [0, 2, 4, 6] assert fs(f2, s) == fsf2(s) # == [0, 1, 4, 9]
s = [2, 4, 6, 8] assert fs(f1, s) == fsf1(s) # == [4, 8, 12, 16] assert fs(f2, s) == fsf2(s) # == [4, 16, 36, 64]</lang>
The program runs without triggering the assertions.
Tcl
<lang tcl>package require Tcl 8.6 proc partial {f1 f2} {
variable ctr coroutine __curry[incr ctr] apply {{f1 f2} {
for {set x [info coroutine]} 1 {} { set x [{*}$f1 $f2 [yield $x]] }
}} $f1 $f2
}</lang> Demonstration: <lang tcl>proc fs {f s} {
set r {} foreach n $s {
lappend r [{*}$f $n]
} return $r
} proc f1 x {expr {$x * 2}} proc f2 x {expr {$x ** 2}} set fsf1 [partial fs f1] set fsf2 [partial fs f2] foreach s {{0 1 2 3} {2 4 6 8}} {
puts "$s ==f1==> [$fsf1 $s]" puts "$s ==f2==> [$fsf2 $s]"
}</lang> Output:
0 1 2 3 ==f1==> 0 2 4 6 0 1 2 3 ==f2==> 0 1 4 9 2 4 6 8 ==f1==> 4 8 12 16 2 4 6 8 ==f2==> 4 16 36 64