tasks a-s
This commit is contained in:
parent
47bf37c096
commit
b83f433714
12433 changed files with 156208 additions and 123 deletions
27
Task/Partial-function-application/0DESCRIPTION
Normal file
27
Task/Partial-function-application/0DESCRIPTION
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
[[wp:Partial 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 <code>v1, v2</code>
|
||||
: Given <code>f(param1, param2)</code>
|
||||
: Then <code>partial(f, param1=v1)</code> returns <code>f'(param2)</code>
|
||||
: And <code>f(param1=v1, param2=v2) == f'(param2=v2)</code> (for any value v2)
|
||||
|
||||
Note that in the partial application of a parameter, (in the above case param1), other parameters are not explicitly 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.<br> 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 returns 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.
|
||||
|
||||
;Notes
|
||||
* In partially applying the functions f1 or f2 to fs, there should be no ''explicit'' mention of any other parameters to fs, although introspection of fs within the partial applicator to find its parameters ''is'' allowed.
|
||||
* This task is more about ''how'' results are generated rather than just getting results.
|
||||
2
Task/Partial-function-application/1META.yaml
Normal file
2
Task/Partial-function-application/1META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
note: Programming language concepts
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
MODE SET = FLEX[0]INT;
|
||||
|
||||
MODE F = PROC(INT)INT,
|
||||
FS = PROC(SET)SET;
|
||||
|
||||
PROC fs = (F f, SET set)SET: (
|
||||
[LWB set:UPB set]INT out;
|
||||
FOR i FROM LWB set TO UPB set DO out[i]:=f(set[i]) OD;
|
||||
out
|
||||
);
|
||||
|
||||
PROC f1 = (INT value)INT: value * 2,
|
||||
f2 = (INT value)INT: value ** 2;
|
||||
|
||||
FS fsf1 = fs(f1,),
|
||||
fsf2 = fs(f2,);
|
||||
|
||||
[4]INT set;
|
||||
FORMAT set fmt = $"("n(UPB set-LWB set)(g(0)", ")g(0)")"l$;
|
||||
|
||||
set := (0, 1, 2, 3);
|
||||
printf((set fmt, fsf1((0, 1, 2, 3)))); # prints (0, 2, 4, 6) #
|
||||
printf((set fmt, fsf2((0, 1, 2, 3)))); # prints (0, 1, 4, 9) #
|
||||
|
||||
set := (2, 4, 6, 8);
|
||||
printf((set fmt, fsf1((2, 4, 6, 8)))); # prints (4, 8, 12, 16) #
|
||||
printf((set fmt, fsf2((2, 4, 6, 8)))) # prints (4, 16, 36, 64) #
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
with Ada.Text_IO;
|
||||
|
||||
procedure Partial_Function_Application is
|
||||
|
||||
type Sequence is array(Positive range <>) of Integer;
|
||||
|
||||
-- declare a function FS with a generic parameter F and a normal parameter S
|
||||
generic
|
||||
with function F(I: Integer) return Integer; -- generic parameter
|
||||
function FS (S: Sequence) return Sequence;
|
||||
|
||||
-- define FS
|
||||
function FS (S: Sequence) return Sequence is
|
||||
Result: Sequence(S'First .. S'Last);
|
||||
begin
|
||||
for Idx in S'Range loop
|
||||
Result(Idx) := F(S(Idx));
|
||||
end loop;
|
||||
return Result;
|
||||
end FS;
|
||||
|
||||
-- define functions F1 and F2
|
||||
function F1(I: Integer) return Integer is
|
||||
begin
|
||||
return 2*I;
|
||||
end F1;
|
||||
|
||||
function F2(I: Integer) return Integer is
|
||||
begin
|
||||
return I**2;
|
||||
end F2;
|
||||
|
||||
-- instantiate the function FS by F1 and F2 (partially apply F1 and F2 to FS)
|
||||
function FSF1 is new FS(F1);
|
||||
function FSF2 is new FS(F2);
|
||||
|
||||
procedure Print(S: Sequence) is
|
||||
begin
|
||||
for Idx in S'Range loop
|
||||
Ada.Text_IO.Put(Integer'Image(S(Idx)));
|
||||
end loop;
|
||||
Ada.Text_IO.New_Line;
|
||||
end Print;
|
||||
|
||||
begin
|
||||
Print(FSF1((0,1,2,3)));
|
||||
Print(FSF2((0,1,2,3)));
|
||||
Print(FSF1((2,4,6,8)));
|
||||
Print(FSF2((2,4,6,8)));
|
||||
end Partial_Function_Application;
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
fsf1 = FNpartial(PROCfs(), FNf1())
|
||||
fsf2 = FNpartial(PROCfs(), FNf2())
|
||||
|
||||
DIM seq(3)
|
||||
PRINT "Calling function fsf1 with sequence 1:"
|
||||
seq() = 0, 1, 2, 3 : PROC(fsf1)(seq())
|
||||
FOR i% = 0 TO 3 : PRINT seq(i%); : NEXT : PRINT
|
||||
PRINT "Calling function fsf1 with sequence 2:"
|
||||
seq() = 2, 4, 6, 8 : PROC(fsf1)(seq())
|
||||
FOR i% = 0 TO 3 : PRINT seq(i%); : NEXT : PRINT
|
||||
PRINT "Calling function fsf2 with sequence 1:"
|
||||
seq() = 0, 1, 2, 3 : PROC(fsf2)(seq())
|
||||
FOR i% = 0 TO 3 : PRINT seq(i%); : NEXT : PRINT
|
||||
PRINT "Calling function fsf2 with sequence 2:"
|
||||
seq() = 2, 4, 6, 8 : PROC(fsf2)(seq())
|
||||
FOR i% = 0 TO 3 : PRINT seq(i%); : NEXT : PRINT
|
||||
END
|
||||
|
||||
REM Create a partial function:
|
||||
DEF FNpartial(RETURN f1%, RETURN f2%)
|
||||
LOCAL f$, p%
|
||||
DIM p% 7 : p%!0 = f1% : p%!4 = f2%
|
||||
f$ = "(s())" + CHR$&F2 + "(&" + STR$~p% + ")(" + \
|
||||
\ CHR$&A4 + "(&" + STR$~(p%+4) + ")(),s()):" + CHR$&E1
|
||||
DIM p% LEN(f$) + 4
|
||||
$(p%+4) = f$ : !p% = p%+4
|
||||
= p%
|
||||
|
||||
REM Replaces the input sequence with the output sequence:
|
||||
DEF PROCfs(RETURN f%, seq())
|
||||
LOCAL i%
|
||||
FOR i% = 0 TO DIM(seq(),1)
|
||||
seq(i%) = FN(^f%)(seq(i%))
|
||||
NEXT
|
||||
ENDPROC
|
||||
|
||||
DEF FNf1(n) = n * 2
|
||||
|
||||
DEF FNf2(n) = n ^ 2
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
#include <utility> // For declval.
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <iterator>
|
||||
#include <iostream>
|
||||
|
||||
/* Partial application helper. */
|
||||
template< class F, class Arg >
|
||||
struct PApply
|
||||
{
|
||||
F f;
|
||||
Arg arg;
|
||||
|
||||
tempalte< class F_, class Arg_ >
|
||||
PApply( F_&& f, Arg_&& arg )
|
||||
: f(std::forward<F_>(f)), arg(std::forward<Arg_>(arg))
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* The return type of F only gets deduced based on the number of arguments
|
||||
* supplied. PApply otherwise has no idea whether f takes 1 or 10 args.
|
||||
*/
|
||||
template< class ... Args >
|
||||
auto operator() ( Args&& ...args )
|
||||
-> decltype( f(arg,std::declval<Args>()...) )
|
||||
{
|
||||
return f( arg, std::forward<Args>(args)... );
|
||||
}
|
||||
};
|
||||
|
||||
template< class F, class Arg >
|
||||
PApply<F,Arg> papply( F&& f, Arg&& arg )
|
||||
{
|
||||
return PApply<F,Arg>( std::forward<F>(f), std::forward<Arg>(arg) );
|
||||
}
|
||||
|
||||
/* Apply f to cont. */
|
||||
template< class F >
|
||||
std::array<int,4> fs( F&& f, std::array<int,4> cont )
|
||||
{
|
||||
std::transform( std::begin(cont), std::end(cont), std::begin(cont),
|
||||
std::forward<F>(f) );
|
||||
return cont;
|
||||
}
|
||||
|
||||
std::ostream& operator << ( std::ostream& out, const std::array<int,4>& c )
|
||||
{
|
||||
std::copy( std::begin(c), std::end(c),
|
||||
std::ostream_iterator<int>(out, ", ") );
|
||||
return out;
|
||||
}
|
||||
|
||||
int f1( int x ) { return x * 2; }
|
||||
int f2( int x ) { return x * x; }
|
||||
|
||||
int main()
|
||||
{
|
||||
std::array<int,4> xs = {{ 0, 1, 2, 3 }};
|
||||
std::array<int,4> ys = {{ 2, 4, 6, 8 }};
|
||||
|
||||
auto fsf1 = papply( fs<decltype(f1)>, f1 );
|
||||
auto fsf2 = papply( fs<decltype(f2)>, f2 );
|
||||
|
||||
std::cout << "xs:\n"
|
||||
<< "\tfsf1: " << fsf1(xs) << '\n'
|
||||
<< "\tfsf2: " << fsf2(xs) << "\n\n"
|
||||
<< "ys:\n"
|
||||
<< "\tfsf1: " << fsf1(ys) << '\n'
|
||||
<< "\tfsf2: " << fsf2(ys) << '\n';
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
class PartialFunctionApplication
|
||||
{
|
||||
static Func<T1, TResult> PartiallyApply<T1, T2, TResult>(Func<T1, T2, TResult> function, T2 argument2)
|
||||
{
|
||||
return argument1 => function(argument1, argument2);
|
||||
}
|
||||
|
||||
static void Main()
|
||||
{
|
||||
var fs = (Func<IEnumerable<int>, Func<int, int>, IEnumerable<int>>)Enumerable.Select;
|
||||
var f1 = (Func<int, int>)(n => n * 2);
|
||||
var f2 = (Func<int, int>)(n => n * n);
|
||||
var fsf1 = PartiallyApply(fs, f1);
|
||||
var fsf2 = PartiallyApply(fs, f2);
|
||||
|
||||
var s = new[] { 0, 1, 2, 3 };
|
||||
Console.WriteLine(string.Join(", ", fsf1(s)));
|
||||
Console.WriteLine(string.Join(", ", fsf2(s)));
|
||||
|
||||
s = new[] { 2, 4, 6, 8 };
|
||||
Console.WriteLine(string.Join(", ", fsf1(s)));
|
||||
Console.WriteLine(string.Join(", ", fsf2(s)));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/wait.h>
|
||||
#include <err.h>
|
||||
|
||||
typedef int (*intfunc)(int);
|
||||
typedef void (*pfunc)(int*, int);
|
||||
|
||||
pfunc partial(intfunc fin)
|
||||
{
|
||||
pfunc f;
|
||||
static int idx = 0;
|
||||
char cc[256], lib[256];
|
||||
FILE *fp;
|
||||
sprintf(lib, "/tmp/stuff%d.so", ++idx);
|
||||
sprintf(cc, "cc -pipe -x c -shared -o %s -", lib);
|
||||
|
||||
fp = popen(cc, "w");
|
||||
fprintf(fp, "#define t typedef\xat int _i,*i;t _i(*__)(_i);__ p =(__)%p;"
|
||||
"void _(i _1, _i l){while(--l>-1)l[_1]=p(l[_1]);}", fin);
|
||||
fclose(fp);
|
||||
|
||||
*(void **)(&f) = dlsym(dlopen(lib, RTLD_LAZY), "_");
|
||||
unlink(lib);
|
||||
return f;
|
||||
}
|
||||
|
||||
int square(int a)
|
||||
{
|
||||
return a * a;
|
||||
}
|
||||
|
||||
int dbl(int a)
|
||||
{
|
||||
return a + a;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int x[] = { 1, 2, 3, 4 };
|
||||
int y[] = { 1, 2, 3, 4 };
|
||||
int i;
|
||||
|
||||
pfunc f = partial(square);
|
||||
pfunc g = partial(dbl);
|
||||
|
||||
printf("partial square:\n");
|
||||
f(x, 4);
|
||||
for (i = 0; i < 4; i++) printf("%d\n", x[i]);
|
||||
|
||||
printf("partial double:\n");
|
||||
g(y, 4);
|
||||
for (i = 0; i < 4; i++) printf("%d\n", y[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
partial square:
|
||||
1
|
||||
4
|
||||
9
|
||||
16
|
||||
partial double:
|
||||
2
|
||||
4
|
||||
6
|
||||
8
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
(defn fs [f s] (map f s))
|
||||
(defn f1 [x] (* 2 x))
|
||||
(defn f2 [x] (* x x))
|
||||
(def fsf1 (partial fs f1))
|
||||
(def fsf2 (partial fs f2))
|
||||
|
||||
(doseq [s [(range 4) (range 2 9 2)]]
|
||||
(println "seq: " s)
|
||||
(println " fsf1: " (fsf1 s))
|
||||
(println " fsf2: " (fsf2 s)))
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
partial = (f, g) ->
|
||||
(s) -> f(g, s)
|
||||
|
||||
fs = (f, s) -> (f(a) for a in s)
|
||||
f1 = (a) -> a * 2
|
||||
f2 = (a) -> a * a
|
||||
fsf1 = partial(fs, f1)
|
||||
fsf2 = partial(fs, f2)
|
||||
|
||||
do ->
|
||||
for seq in [[0..3], [2,4,6,8]]
|
||||
console.log fsf1 seq
|
||||
console.log fsf2 seq
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
> coffee partials.coffee
|
||||
[ 0, 2, 4, 6 ]
|
||||
[ 0, 1, 4, 9 ]
|
||||
[ 4, 8, 12, 16 ]
|
||||
[ 4, 16, 36, 64 ]
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
(defun fs (f s) (mapcar f s))
|
||||
(defun f1 (i) (* i 2))
|
||||
(defun f2 (i) (expt i 2))
|
||||
|
||||
(defun partial (func &rest args1)
|
||||
(lambda (&rest args2) (apply func (append args1 args2))))
|
||||
(defvar fsf1 (partial #'fs #'f1))
|
||||
(defvar fsf2 (partial #'fs #'f2))
|
||||
|
||||
(dolist (seq '((0 1 2 3) (2 4 6 8)))
|
||||
(format t "~%seq: ~A~% fsf1 seq: ~A~% fsf2 seq: ~A"
|
||||
seq (funcall fsf1 seq) (funcall fsf2 seq)))
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import std.stdio, std.algorithm, std.traits;
|
||||
|
||||
auto fs(alias f)(in int[] s) /*pure nothrow*/
|
||||
if (isCallable!f && ParameterTypeTuple!f.length == 1) {
|
||||
return map!f(s);
|
||||
}
|
||||
|
||||
int f1(in int x) pure nothrow { return x * 2; }
|
||||
int f2(in int x) pure nothrow { return x ^^ 2; }
|
||||
|
||||
alias fs!f1 fsf1;
|
||||
alias fs!f2 fsf2;
|
||||
|
||||
void main() {
|
||||
foreach (d; [[0, 1, 2, 3], [2, 4, 6, 8]]) {
|
||||
writeln(fsf1(d));
|
||||
writeln(fsf2(d));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
def pa(f, args1) {
|
||||
return def partial {
|
||||
match [`run`, args2] {
|
||||
E.call(f, "run", args1 + args2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def fs(f, s) {
|
||||
var r := []
|
||||
for n in s {
|
||||
r with= f(n)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
def f1(n) { return n * 2 }
|
||||
def f2(n) { return n ** 2 }
|
||||
|
||||
def fsf1 := pa(fs, [f1])
|
||||
def fsf2 := pa(fs, [f2])
|
||||
for s in [0..3, [2, 4, 6, 8]] {
|
||||
for f in [fsf1, fsf2] {
|
||||
println(f(s))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
fs f s = map f s
|
||||
f1 value = value * 2
|
||||
f2 value = value ^ 2
|
||||
|
||||
fsf1 = fs f1
|
||||
fsf2 = fs f2
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
print $ fsf1 [0, 1, 2, 3] -- prints [0, 2, 4, 6]
|
||||
print $ fsf2 [0, 1, 2, 3] -- prints [0, 1, 4, 9]
|
||||
print $ fsf1 [2, 4, 6, 8] -- prints [4, 8, 12, 16]
|
||||
print $ fsf2 [2, 4, 6, 8] -- prints [4, 16, 36, 64]
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
link printf
|
||||
|
||||
procedure main()
|
||||
fsf1 := partial(fs,f1)
|
||||
fsf2 := partial(fs,f2)
|
||||
every s := [ 0, 1, 2, 3 ] |
|
||||
[ 2, 4, 6, 8 ] do {
|
||||
printf("\ns := %s\n",list2string(s))
|
||||
printf("fsf1(s) := %s\n",list2string(fsf1(s)))
|
||||
printf("fsf2(s) := %s\n",list2string(fsf2(s)))
|
||||
}
|
||||
end
|
||||
|
||||
procedure partial(f,g) #: partial application of f & g
|
||||
@( p := create repeat {
|
||||
s := (r@&source)[1] # return r / get argument s
|
||||
r := f(g,s) # apply f(g,...)
|
||||
}
|
||||
) # create and activate procedure p
|
||||
return p
|
||||
end
|
||||
|
||||
procedure fs(f,s) #: return list where f is applied to each element of s
|
||||
every put(r := [], f(!s))
|
||||
return r
|
||||
end
|
||||
|
||||
procedure f1(n) # double
|
||||
return n * 2
|
||||
end
|
||||
|
||||
procedure f2(n) #: square
|
||||
return n ^ 2
|
||||
end
|
||||
|
||||
procedure list2string(L) #: format list as a string
|
||||
every (s := "[ ") ||:= !L || " "
|
||||
return s || "]"
|
||||
end
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
fs=:1 :'u"0 y'
|
||||
f1=:*&2
|
||||
f2=:^&2
|
||||
fsf1=:f1 fs
|
||||
fsf2=:f2 fs
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
f1 i.4
|
||||
0 2 4 6
|
||||
f2 i.4
|
||||
0 1 4 9
|
||||
f1 1+i.4
|
||||
2 4 6 8
|
||||
f2 f1 1+i.4
|
||||
4 16 36 64
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
crippled=:1 :0
|
||||
assert.1=#y
|
||||
u y
|
||||
)
|
||||
|
||||
F1=: f1 crippled
|
||||
F2=: f2 crippled
|
||||
fsF1=: F1 fs
|
||||
fsF2=: F2 fs
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
F1 i.4
|
||||
|assertion failure: F1
|
||||
| 1=#y
|
||||
fsF1 i.4
|
||||
0 2 4 6
|
||||
NB. and so on...
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
import java.util.Arrays;
|
||||
|
||||
public class PartialApplication {
|
||||
interface IntegerFunction {
|
||||
int call(int arg);
|
||||
}
|
||||
|
||||
// Original method fs(f, s).
|
||||
static int[] fs(IntegerFunction f, int[] s) {
|
||||
int[] r = new int[s.length];
|
||||
for (int i = 0; i < s.length; i++)
|
||||
r[i] = f.call(s[i]);
|
||||
return r;
|
||||
}
|
||||
|
||||
interface SequenceFunction {
|
||||
int[] call(int[] arg);
|
||||
}
|
||||
|
||||
// Curried method fs(f).call(s),
|
||||
// necessary for partial application.
|
||||
static SequenceFunction fs(final IntegerFunction f) {
|
||||
return new SequenceFunction() {
|
||||
public int[] call(int[] s) {
|
||||
// Call original method.
|
||||
return fs(f, s);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static IntegerFunction f1 = new IntegerFunction() {
|
||||
public int call(int i) {
|
||||
return i * 2;
|
||||
}
|
||||
};
|
||||
|
||||
static IntegerFunction f2 = new IntegerFunction() {
|
||||
public int call(int i) {
|
||||
return i * i;
|
||||
}
|
||||
};
|
||||
|
||||
static SequenceFunction fsf1 = fs(f1); // Partial application.
|
||||
|
||||
static SequenceFunction fsf2 = fs(f2);
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[][] sequences = {
|
||||
{ 0, 1, 2, 3 },
|
||||
{ 2, 4, 6, 8 },
|
||||
};
|
||||
|
||||
for (int[] array : sequences) {
|
||||
System.out.printf(
|
||||
"array: %s\n" +
|
||||
" fsf1(array): %s\n" +
|
||||
" fsf2(array): %s\n",
|
||||
Arrays.toString(array),
|
||||
Arrays.toString(fsf1.call(array)),
|
||||
Arrays.toString(fsf2.call(array)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
import java.util.Arrays;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class PartialApplication {
|
||||
// Original method fs(f, s).
|
||||
static Integer[] fs(Function<Integer, Integer> f, Integer[] s) {
|
||||
Integer[] r = new Integer[s.length];
|
||||
for (int i = 0; i < s.length; i++)
|
||||
r[i] = f.apply(s[i]);
|
||||
return r;
|
||||
}
|
||||
|
||||
// Curried method fs(f).apply(s),
|
||||
// necessary for partial application.
|
||||
static Function<Integer[], Integer[]> fs(Function<Integer, Integer> f) {
|
||||
return s -> fs(f, s);
|
||||
}
|
||||
|
||||
static Function<Integer, Integer> f1 = i -> i * 2;
|
||||
|
||||
static Function<Integer, Integer> f2 = i -> i * i;
|
||||
|
||||
static Function<Integer[], Integer[]> fsf1 = fs(f1); // Partial application.
|
||||
|
||||
static Function<Integer[], Integer[]> fsf2 = fs(f2);
|
||||
|
||||
public static void main(String[] args) {
|
||||
Integer[][] sequences = {
|
||||
{ 0, 1, 2, 3 },
|
||||
{ 2, 4, 6, 8 },
|
||||
};
|
||||
|
||||
for (Integer[] array : sequences) {
|
||||
System.out.printf(
|
||||
"array: %s\n" +
|
||||
" fsf1(array): %s\n" +
|
||||
" fsf2(array): %s\n",
|
||||
Arrays.toString(array),
|
||||
Arrays.toString(fsf1.apply(array)),
|
||||
Arrays.toString(fsf2.apply(array)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
fs[f_, s_] := Map[f, s]
|
||||
f1 [n_] := n*2
|
||||
f2 [n_] := n^2
|
||||
fsf1[s_] := fs[f1, s]
|
||||
fsf2[s_] := fs[f2, s]
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
:- module partial_function_application.
|
||||
:- interface.
|
||||
|
||||
:- import_module io.
|
||||
|
||||
:- pred main(io::di, io::uo) is det.
|
||||
|
||||
:- implementation.
|
||||
:- import_module int, list.
|
||||
|
||||
main(!IO) :-
|
||||
io.write((fsf1)([0, 1, 2, 3]), !IO), io.nl(!IO),
|
||||
io.write((fsf2)([0, 1, 2, 3]), !IO), io.nl(!IO),
|
||||
io.write((fsf1)([2, 4, 6, 8]), !IO), io.nl(!IO),
|
||||
io.write((fsf2)([2, 4, 6, 8]), !IO), io.nl(!IO).
|
||||
|
||||
:- func fs(func(V) = V, list(V)) = list(V).
|
||||
|
||||
fs(_, []) = [].
|
||||
fs(F, [V | Vs]) = [F(V) | fs(F, Vs)].
|
||||
|
||||
:- func f1(int) = int.
|
||||
|
||||
f1(V) = V * 2.
|
||||
|
||||
:- func f2(int) = int.
|
||||
|
||||
f2(V) = V * V.
|
||||
|
||||
:- func fsf1 = (func(list(int)) = list(int)).
|
||||
|
||||
fsf1 = fs(f1).
|
||||
|
||||
:- func fsf2 = (func(list(int)) = list(int)).
|
||||
|
||||
fsf2 = fs(f2).
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using System.Console;
|
||||
|
||||
module Partial
|
||||
{
|
||||
fs[T] (f : T -> T, s : list[T]) : list[T]
|
||||
{
|
||||
$[f(x)| x in s]
|
||||
}
|
||||
|
||||
f1 (x : int) : int
|
||||
{
|
||||
x * 2
|
||||
}
|
||||
|
||||
f2 (x : int) : int
|
||||
{
|
||||
x * x
|
||||
}
|
||||
|
||||
curry[T, U, V] (f : T * U -> V, x : T) : U -> V
|
||||
{
|
||||
f(x, _)
|
||||
}
|
||||
|
||||
// curryr() isn't actually used in this task, I just include it for symmetry
|
||||
curryr[T, U, V] (f : T * U -> V, x : U) : T -> V
|
||||
{
|
||||
f(_, x)
|
||||
}
|
||||
|
||||
Main() : void
|
||||
{
|
||||
def fsf1 = curry(fs, f1);
|
||||
def fsf2 = curry(fs, f2);
|
||||
def test1 = $[0 .. 3];
|
||||
def test2 = $[x | x in [2 .. 8], x % 2 == 0];
|
||||
|
||||
WriteLine (fsf1(test1));
|
||||
WriteLine (fsf1(test2));
|
||||
WriteLine (fsf2(test1));
|
||||
WriteLine (fsf2(test2));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#
|
||||
let fs f s = List.map f s
|
||||
let f1 value = value * 2
|
||||
let f2 value = value * value
|
||||
|
||||
let fsf1 = fs f1
|
||||
let fsf2 = fs f2
|
||||
;;
|
||||
val fs : ('a -> 'b) -> 'a list -> 'b list = <fun>
|
||||
val f1 : int -> int = <fun>
|
||||
val f2 : int -> int = <fun>
|
||||
val fsf1 : int list -> int list = <fun>
|
||||
val fsf2 : int list -> int list = <fun>
|
||||
|
||||
# fsf1 [0; 1; 2; 3];;
|
||||
- : int list = [0; 2; 4; 6]
|
||||
# fsf2 [0; 1; 2; 3];;
|
||||
- : int list = [0; 1; 4; 9]
|
||||
# fsf1 [2; 4; 6; 8];;
|
||||
- : int list = [4; 8; 12; 16]
|
||||
# fsf2 [2; 4; 6; 8];;
|
||||
- : int list = [4; 16; 36; 64]
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#include <order/interpreter.h>
|
||||
|
||||
#define ORDER_PP_DEF_8fs ORDER_PP_FN( 8fn(8F, 8S, 8seq_map(8F, 8S)) )
|
||||
|
||||
#define ORDER_PP_DEF_8f1 ORDER_PP_FN( 8fn(8V, 8times(8V, 2)) )
|
||||
|
||||
#define ORDER_PP_DEF_8f2 ORDER_PP_FN( 8fn(8V, 8times(8V, 8V)) )
|
||||
|
||||
ORDER_PP(
|
||||
8let((8F, 8fs(8f1))
|
||||
(8G, 8fs(8f2)),
|
||||
8do(
|
||||
8print(8ap(8F, 8seq(0, 1, 2, 3)) 8comma 8space),
|
||||
8print(8ap(8G, 8seq(0, 1, 2, 3)) 8comma 8space),
|
||||
8print(8ap(8F, 8seq(2, 4, 6, 8)) 8comma 8space),
|
||||
8print(8ap(8G, 8seq(2, 4, 6, 8))))) )
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
sub fs ( Code $f, @s ) { @s.map: { .$f } }
|
||||
|
||||
sub f1 ( $n ) { $n * 2 }
|
||||
sub f2 ( $n ) { $n ** 2 }
|
||||
|
||||
my &fsf1 := &fs.assuming: f => &f1;
|
||||
my &fsf2 := &fs.assuming: f => &f2;
|
||||
|
||||
for [1..3], [2, *+2 ... 8] X &fsf1, &fsf2 -> $s, $f {
|
||||
say ~ $f.($s);
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
sub fs(&) {
|
||||
my $func = shift;
|
||||
sub { map $func->($_), @_ }
|
||||
}
|
||||
|
||||
sub double($) { shift() * 2 }
|
||||
sub square($) { shift() ** 2 }
|
||||
|
||||
my $fs_double = fs(\&double);
|
||||
my $fs_square = fs(\&square);
|
||||
|
||||
my @s = 0 .. 3;
|
||||
print "fs_double(@s): @{[ $fs_double->(@s) ]}\n";
|
||||
print "fs_square(@s): @{[ $fs_square->(@s) ]}\n";
|
||||
|
||||
@s = (2, 4, 6, 8);
|
||||
print "fs_double(@s): @{[ $fs_double->(@s) ]}\n";
|
||||
print "fs_square(@s): @{[ $fs_square->(@s) ]}\n";
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
(def 'fs mapcar)
|
||||
(de f1 (N) (* 2 N))
|
||||
(de f2 (N) (* N N))
|
||||
|
||||
(de partial (F1 F2)
|
||||
(curry (F1 F2) @
|
||||
(pass F1 F2) ) )
|
||||
|
||||
(def 'fsf1 (partial fs f1))
|
||||
(def 'fsf2 (partial fs f2))
|
||||
|
||||
(for S '((0 1 2 3) (2 4 6 8))
|
||||
(println (fsf1 S))
|
||||
(println (fsf2 S)) )
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
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]).
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
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]
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
def partial(f, g):
|
||||
def fg(*x): return f(g, *x)
|
||||
return fg
|
||||
|
||||
def fs(f, *x): return [ f(a) for a in x]
|
||||
def f1(a): return a * 2
|
||||
def f2(a): return a * a
|
||||
|
||||
fsf1 = partial(fs, f1)
|
||||
fsf2 = partial(fs, f2)
|
||||
|
||||
print fsf1(1, 2, 3, 4)
|
||||
print fsf2(1, 2, 3, 4)
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
partially.apply <- function(f, ...) {
|
||||
capture <- list(...)
|
||||
function(...) {
|
||||
do.call(f, c(capture, list(...)))
|
||||
}
|
||||
}
|
||||
|
||||
fs <- function(f, ...) sapply(list(...), f)
|
||||
f1 <- function(x) 2*x
|
||||
f2 <- function(x) x^2
|
||||
|
||||
fsf1 <- partially.apply(fs, f1)
|
||||
fsf2 <- partially.apply(fs, f2)
|
||||
|
||||
fsf1(0:3)
|
||||
fsf2(0:3)
|
||||
fsf1(seq(2,8,2))
|
||||
fsf2(seq(2,8,2))
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#lang racket
|
||||
|
||||
(define (fs f s) (map f s))
|
||||
(define (f1 n) (* n 2))
|
||||
(define (f2 n) (* n n))
|
||||
|
||||
(define fsf1 (curry fs f1))
|
||||
(define fsf2 (curry fs f2))
|
||||
|
||||
(fsf1 '(0 1 2 3))
|
||||
(fsf1 '(2 4 6 8))
|
||||
(fsf2 '(0 1 2 3))
|
||||
(fsf2 '(2 4 6 8))
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
fs = proc { |f, s| s.map &f }
|
||||
f1 = proc { |n| n * 2 }
|
||||
f2 = proc { |n| n ** 2 }
|
||||
fsf1 = fs.curry[f1]
|
||||
fsf2 = fs.curry[f2]
|
||||
|
||||
[0..3, (2..8).step(2)].each do |e|
|
||||
p fsf1[e]
|
||||
p fsf2[e]
|
||||
end
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
def fs(f:Int=>Int, s:List[Int])=s map f
|
||||
def f1(x:Int)=x*2
|
||||
def f2(x:Int)=x*x
|
||||
|
||||
def fsf1=fs(f1,_:List[Int])
|
||||
def fsf2=fs(f2,_:List[Int])
|
||||
|
||||
println(fsf1(List(0,1,2,3)))
|
||||
println(fsf1(List(2,4,6,8)))
|
||||
println(fsf2(List(0,1,2,3)))
|
||||
println(fsf2(List(2,4,6,8)))
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
| f1 f2 fs fsf1 fsf2 partial |
|
||||
|
||||
partial := [ :afs :af | [ :s | afs value: af value: s ] ].
|
||||
|
||||
fs := [ :f :s | s collect: [ :x | f value: x ]].
|
||||
f1 := [ :x | x * 2 ].
|
||||
f2:= [ :x | x * x ].
|
||||
fsf1 := partial value: fs value: f1.
|
||||
fsf2 := partial value: fs value: f2.
|
||||
|
||||
fsf1 value: (0 to: 3).
|
||||
" #(0 2 4 6)"
|
||||
fsf2 value: (0 to: 3).
|
||||
" #(0 1 4 9)"
|
||||
|
||||
fsf1 value: #(2 4 6 8).
|
||||
" #(4 8 12 16)"
|
||||
fsf2 value: #(2 4 6 8).
|
||||
" #(4 16 36 64)"
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
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
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
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]"
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue