Partial function application

From Rosetta Code
Partial function application is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

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) returns f'(param2)
And f(param1=v1, param2=v2) == f'(param2=v2) (for any value v2)

Note that in the partial application of a parameter, (in the above case param1), other parameters are not explicitely mentioned. This is a recurring feature of partial function application.

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.

J

Given:

<lang j>fs=:1 :'u"0 y' f1=:*&2 f2=:^&2 fsf1=:f1 fs fsf2=:f2 fs</lang>

The required examples might look like this:

<lang j> fsf1 i.4 0 2 4 6

  fsf2 i.4

0 1 4 9

  fsf1 fsf1 1+i.4

4 8 12 16

  fsf2 fsf1 1+i.4

4 16 36 64</lang>

Prolog

Works with SWI-Prolog. <lang Prolog>fs(P, S, S1) :- maplist(P, S, S1).

f1(X, Y) :- Y is 2 * X.

f2(X, Y) :- Y is X * X.

create_partial(P, fs(P)).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% fs :- % partial functions create_partial(f1, FSF1), create_partial(f2, FSF2),

S1 = [0,1,2,3], call(FSF1,S1, S11), format('~w : ~w ==> ~w~n',[FSF1, S1, S11]), call(FSF1,S1, S12), format('~w : ~w ==> ~w~n',[FSF2, S1, S12]),

S2 = [2,4,6,8], call(FSF1,S2, S21), format('~w : ~w ==> ~w~n',[FSF2, S2, S21]), call(FSF2,S2, S22), format('~w : ~w ==> ~w~n',[FSF1, S2, S22]). </lang> Output :

?- fs.
fs(f1) : [0,1,2,3] ==> [0,2,4,6]
fs(f2) : [0,1,2,3] ==> [0,1,4,9]
fs(f1) : [2,4,6,8] ==> [4,8,12,16]
fs(f2) : [2,4,6,8] ==> [4,16,36,64]
true.

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

Works with: Tcl version 8.6

<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