Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
3
Task/Partial-function-application/00-META.yaml
Normal file
3
Task/Partial-function-application/00-META.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Partial_function_application
|
||||
note: Programming language concepts
|
||||
32
Task/Partial-function-application/00-TASK.txt
Normal file
32
Task/Partial-function-application/00-TASK.txt
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
[[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.
|
||||
<br><br>
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
F partial(f, g)
|
||||
F fg(x)
|
||||
R @f(@g, x)
|
||||
R fg
|
||||
|
||||
F main()
|
||||
F ffs(f, x)
|
||||
R x.map(a -> @f(a))
|
||||
F f1(a) {R a * 2}
|
||||
F f2(a) {R a * a}
|
||||
|
||||
V fsf1 = partial(ffs, f1)
|
||||
V fsf2 = partial(ffs, f2)
|
||||
|
||||
print(fsf1([1, 2, 3, 4]))
|
||||
print(fsf2([1, 2, 3, 4]))
|
||||
|
||||
main()
|
||||
|
|
@ -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,62 @@
|
|||
-- PARTIAL APPLICATION --------------------------------------------
|
||||
|
||||
on f1(x)
|
||||
x * 2
|
||||
end f1
|
||||
|
||||
on f2(x)
|
||||
x * x
|
||||
end f2
|
||||
|
||||
on run
|
||||
|
||||
tell curry(map)
|
||||
set fsf1 to |λ|(f1)
|
||||
set fsf2 to |λ|(f2)
|
||||
end tell
|
||||
|
||||
{fsf1's |λ|({0, 1, 2, 3}), ¬
|
||||
fsf2's |λ|({0, 1, 2, 3}), ¬
|
||||
fsf1's |λ|({2, 4, 6, 8}), ¬
|
||||
fsf2's |λ|({2, 4, 6, 8})}
|
||||
end run
|
||||
|
||||
|
||||
-- GENERIC FUNCTIONS --------------------------------------------
|
||||
|
||||
-- curry :: (Script|Handler) -> Script
|
||||
on curry(f)
|
||||
script
|
||||
on |λ|(a)
|
||||
script
|
||||
on |λ|(b)
|
||||
|λ|(a, b) of mReturn(f)
|
||||
end |λ|
|
||||
end script
|
||||
end |λ|
|
||||
end script
|
||||
end curry
|
||||
|
||||
-- map :: (a -> b) -> [a] -> [b]
|
||||
on map(f, xs)
|
||||
tell mReturn(f)
|
||||
set lng to length of xs
|
||||
set lst to {}
|
||||
repeat with i from 1 to lng
|
||||
set end of lst to |λ|(item i of xs, i, xs)
|
||||
end repeat
|
||||
return lst
|
||||
end tell
|
||||
end map
|
||||
|
||||
-- Lift 2nd class handler function into 1st class script wrapper
|
||||
-- mReturn :: Handler -> Script
|
||||
on mReturn(f)
|
||||
if class of f is script then
|
||||
f
|
||||
else
|
||||
script
|
||||
property |λ| : f
|
||||
end script
|
||||
end if
|
||||
end mReturn
|
||||
|
|
@ -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,11 @@
|
|||
( (fs=/('(x./('(y.map'($x.$y))))))
|
||||
& (f1=/('(x.$x*2)))
|
||||
& (f2=/('(x.$x^2)))
|
||||
& (partial=/('(x./('(y.($x)$($y))))))
|
||||
& (!partial$!fs)$!f1:?fsf1
|
||||
& (!partial$!fs)$!f2:?fsf2
|
||||
& out$(!fsf1$(0 1 2 3))
|
||||
& out$(!fsf2$(0 1 2 3))
|
||||
& out$(!fsf1$(2 4 6 8))
|
||||
& out$(!fsf2$(2 4 6 8))
|
||||
);
|
||||
|
|
@ -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;
|
||||
|
||||
template< 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,45 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
static class PartialApplicationDynamic
|
||||
{
|
||||
// Create a matching delegate type to simplify delegate creation.
|
||||
delegate IEnumerable<TResult> fsDelegate<TSource, TResult>(Func<TSource, TResult> f, IEnumerable<TSource> s);
|
||||
|
||||
static IEnumerable<TResult> fs<TSource, TResult>(Func<TSource, TResult> f, IEnumerable<TSource> s) => s.Select(f);
|
||||
|
||||
static dynamic f1(dynamic x) => x * 2;
|
||||
|
||||
static dynamic f2(dynamic x) => x * x;
|
||||
|
||||
static T[] ArrayConcat<T>(T[] arr1, T[] arr2)
|
||||
{
|
||||
var result = new T[arr1.Length + arr2.Length];
|
||||
Array.Copy(arr1, result, arr1.Length);
|
||||
Array.Copy(arr2, 0, result, 1, arr2.Length);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Use a specialized params delegate to simplify calling at the risk of inadvertent params expansion.
|
||||
delegate TResult partialDelegate<TParams, TResult>(params TParams[] args);
|
||||
static partialDelegate<dynamic, TResult> PartialApplyDynamic<TDelegate, TResult>(TDelegate f, params dynamic[] args) where TDelegate : Delegate
|
||||
{
|
||||
return rest => (TResult)f.DynamicInvoke(ArrayConcat(args, rest).Cast<dynamic>().ToArray());
|
||||
}
|
||||
|
||||
static void Main()
|
||||
{
|
||||
// Cast to object to avoid params expansion of the arrays.
|
||||
object args1 = new object[] { 0, 1, 2, 3 };
|
||||
object args2 = new object[] { 2, 4, 6, 8 };
|
||||
|
||||
var fsf1 = PartialApplyDynamic<fsDelegate<dynamic, dynamic>, IEnumerable<dynamic>>(fs, new Func<dynamic, dynamic>(f1));
|
||||
var fsf2 = PartialApplyDynamic<fsDelegate<dynamic, dynamic>, IEnumerable<dynamic>>(fs, new Func<dynamic, dynamic>(f2));
|
||||
|
||||
Console.WriteLine("fsf1, 0-3: " + string.Join(", ", fsf1(args1)));
|
||||
Console.WriteLine("fsf1, evens: " + string.Join(", ", fsf1(args2)));
|
||||
Console.WriteLine("fsf2, 0-3: " + string.Join(", ", fsf2(args1)));
|
||||
Console.WriteLine("fsf2, evens: " + string.Join(", ", fsf2(args2)));
|
||||
}
|
||||
}
|
||||
|
|
@ -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,17 @@
|
|||
shared void run() {
|
||||
|
||||
function fs(Integer f(Integer n), {Integer*} s) => s.map(f);
|
||||
|
||||
function f1(Integer n) => n * 2;
|
||||
function f2(Integer n) => n ^ 2;
|
||||
|
||||
value fsCurried = curry(fs);
|
||||
value fsf1 = fsCurried(f1);
|
||||
value fsf2 = fsCurried(f2);
|
||||
|
||||
value ints = 0..3;
|
||||
print("fsf1(``ints``) is ``fsf1(ints)`` and fsf2(``ints``) is ``fsf2(ints)``");
|
||||
|
||||
value evens = (2..8).by(2);
|
||||
print("fsf1(``evens``) is ``fsf1(evens)`` and fsf2(``evens``) is ``fsf2(evens)``");
|
||||
}
|
||||
|
|
@ -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,20 @@
|
|||
(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))))
|
||||
|
||||
(setf (symbol-function 'fsf1) (partial #'fs #'f1))
|
||||
(setf (symbol-function '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
|
||||
(fsf1 seq)
|
||||
(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 s.map!f;
|
||||
}
|
||||
|
||||
int f1(in int x) pure nothrow { return x * 2; }
|
||||
int f2(in int x) pure nothrow { return x ^^ 2; }
|
||||
|
||||
alias fsf1 = fs!f1;
|
||||
alias fsf2 = fs!f2;
|
||||
|
||||
void main() {
|
||||
foreach (const d; [[0, 1, 2, 3], [2, 4, 6, 8]]) {
|
||||
d.fsf1.writeln;
|
||||
d.fsf2.writeln;
|
||||
}
|
||||
}
|
||||
|
|
@ -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,12 @@
|
|||
(define $fs (map $1 $2))
|
||||
|
||||
(define $f1 (* $ 2))
|
||||
(define $f2 (power $ 2))
|
||||
|
||||
(define $fsf1 (fs f1 $))
|
||||
(define $fsf2 (fs f2 $))
|
||||
|
||||
(test (fsf1 {0 1 2 3}))
|
||||
(test (fsf2 {0 1 2 3}))
|
||||
(test (fsf1 {2 4 6 8}))
|
||||
(test (fsf2 {2 4 6 8}))
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{0 2 4 6}
|
||||
{0 1 4 9}
|
||||
{4 8 12 16}
|
||||
{4 16 36 64}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import system'collections;
|
||||
import system'routines;
|
||||
import extensions;
|
||||
|
||||
public program()
|
||||
{
|
||||
var partial := (afs,af => (s => afs(af, s)));
|
||||
|
||||
var fs := (f,s => s.selectBy:(x => f(x)).summarize(new ArrayList()).toArray());
|
||||
var f1 := (x => x * 2);
|
||||
var f2 := (x => x * x);
|
||||
|
||||
var fsf1 := partial(fs, f1);
|
||||
var fsf2 := partial(fs, f2);
|
||||
|
||||
console.printLine(fsf1(new int[]{2,4,6,8}).toString());
|
||||
console.printLine(fsf2(new int[]{2,4,6,8}).toString())
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
let fs f s = List.map f s
|
||||
let f1 n = n * 2
|
||||
let f2 n = n * n
|
||||
|
||||
let fsf1 = fs f1
|
||||
let fsf2 = fs f2
|
||||
|
||||
printfn "%A" (fsf1 [0; 1; 2; 3])
|
||||
printfn "%A" (fsf1 [2; 4; 6; 8])
|
||||
printfn "%A" (fsf2 [0; 1; 2; 3])
|
||||
printfn "%A" (fsf2 [2; 4; 6; 8])
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
USING: kernel math prettyprint sequences ;
|
||||
IN: rosetta-code.partial-function-application
|
||||
|
||||
ALIAS: fs map
|
||||
: f1 ( n -- m ) 2 * ;
|
||||
: f2 ( n -- m ) dup * ;
|
||||
: fsf1 ( s -- s' ) [ f1 ] fs ;
|
||||
: fsf2 ( s -- s' ) [ f2 ] fs ;
|
||||
|
||||
{ 0 1 2 3 } [ fsf1 . ] [ fsf2 . ] bi
|
||||
{ 2 4 6 8 } [ fsf1 . ] [ fsf2 . ] bi
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fs = map
|
||||
f1 = (* 2)
|
||||
f2 = (^ 2)
|
||||
|
||||
fsf1 = fs.curry( f1 )
|
||||
fsf2 = fs.curry( f2 )
|
||||
|
||||
println( fsf1(0..3) )
|
||||
println( fsf2(0..3) )
|
||||
println( fsf1(2..8 by 2) )
|
||||
println( fsf2(2..8 by 2) )
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Using a method bound to a function type:
|
||||
|
||||
// fn is a simple function taking an integer and returning another.
|
||||
type fn func(int) int
|
||||
|
||||
// fs applies fn to each argument returning all results.
|
||||
func (f fn) fs(s ...int) (r []int) {
|
||||
for _, i := range s {
|
||||
r = append(r, f(i))
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// Two simple functions for demonstration.
|
||||
func f1(i int) int { return i * 2 }
|
||||
func f2(i int) int { return i * i }
|
||||
|
||||
// Another way:
|
||||
|
||||
// addn returns a function that adds n to a sequence of numbers
|
||||
func addn(n int) func(...int) []int {
|
||||
return func(s ...int) []int {
|
||||
var r []int
|
||||
for _, i := range s {
|
||||
r = append(r, n+i)
|
||||
}
|
||||
return r
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Turning a method into a function bound to it's reciever:
|
||||
fsf1 := fn(f1).fs
|
||||
fsf2 := fn(f2).fs
|
||||
// Or using a function that returns a function:
|
||||
fsf3 := addn(100)
|
||||
|
||||
s := []int{0, 1, 2, 3}
|
||||
fmt.Println("For s =", s)
|
||||
fmt.Println(" fsf1:", fsf1(s...)) // Called with a slice
|
||||
fmt.Println(" fsf2:", fsf2(0, 1, 2, 3)) // ... or with individual arguments
|
||||
fmt.Println(" fsf3:", fsf3(0, 1, 2, 3))
|
||||
fmt.Println(" fsf2(fsf1):", fsf2(fsf1(s...)...))
|
||||
|
||||
s = []int{2, 4, 6, 8}
|
||||
fmt.Println("For s =", s)
|
||||
fmt.Println(" fsf1:", fsf1(2, 4, 6, 8))
|
||||
fmt.Println(" fsf2:", fsf2(s...))
|
||||
fmt.Println(" fsf3:", fsf3(s...))
|
||||
fmt.Println(" fsf3(fsf1):", fsf3(fsf1(s...)...))
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
def fs = { fn, values -> values.collect { fn(it) } }
|
||||
def f1 = { v -> v * 2 }
|
||||
def f2 = { v -> v ** 2 }
|
||||
def fsf1 = fs.curry(f1)
|
||||
def fsf2 = fs.curry(f2)
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[(0..3), (2..8).step(2)].each { seq ->
|
||||
println "fsf1$seq = ${fsf1(seq)}"
|
||||
println "fsf2$seq = ${fsf2(seq)}"
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
fs = map
|
||||
f1 = (* 2)
|
||||
f2 = (^ 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,68 @@
|
|||
import java.util.Arrays;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.IntUnaryOperator;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface PartialApplication<INPUT1, INPUT2, OUTPUT> extends BiFunction<INPUT1, INPUT2, OUTPUT> {
|
||||
// Original method fs(f, s).
|
||||
public static int[] fs(IntUnaryOperator f, int[] s) {
|
||||
return Arrays.stream(s)
|
||||
.parallel()
|
||||
.map(f::applyAsInt)
|
||||
.toArray()
|
||||
;
|
||||
}
|
||||
|
||||
// Currying method f.apply(a).apply(b),
|
||||
// in lieu of f.apply(a, b),
|
||||
// necessary for partial application.
|
||||
public default Function<INPUT2, OUTPUT> apply(INPUT1 input1) {
|
||||
return input2 -> apply(input1, input2);
|
||||
}
|
||||
|
||||
// Original method fs turned into a partially-applicable function.
|
||||
public static final PartialApplication<IntUnaryOperator, int[], int[]> fs = PartialApplication::fs;
|
||||
|
||||
public static final IntUnaryOperator f1 = i -> i + i;
|
||||
|
||||
public static final IntUnaryOperator f2 = i -> i * i;
|
||||
|
||||
public static final UnaryOperator<int[]> fsf1 = fs.apply(f1)::apply; // Partial application.
|
||||
|
||||
public static final UnaryOperator<int[]> fsf2 = fs.apply(f2)::apply;
|
||||
|
||||
public static void main(String... args) {
|
||||
int[][] sequences = {
|
||||
{0, 1, 2, 3},
|
||||
{2, 4, 6, 8},
|
||||
};
|
||||
|
||||
Arrays.stream(sequences)
|
||||
.parallel()
|
||||
.map(array ->
|
||||
Stream.of(
|
||||
array,
|
||||
fsf1.apply(array),
|
||||
fsf2.apply(array)
|
||||
)
|
||||
.parallel()
|
||||
.map(Arrays::toString)
|
||||
.toArray()
|
||||
)
|
||||
.map(array ->
|
||||
String.format(
|
||||
String.join("\n",
|
||||
"array: %s",
|
||||
" fsf1(array): %s",
|
||||
" fsf2(array): %s"
|
||||
),
|
||||
array
|
||||
)
|
||||
)
|
||||
.forEachOrdered(System.out::println)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
var f1 = function (x) { return x * 2; },
|
||||
f2 = function (x) { return x * x; },
|
||||
|
||||
fs = function (f, s) {
|
||||
return function (s) {
|
||||
return s.map(f);
|
||||
}
|
||||
},
|
||||
|
||||
fsf1 = fs(f1),
|
||||
fsf2 = fs(f2);
|
||||
|
||||
// Test
|
||||
[
|
||||
fsf1([0, 1, 2, 3]),
|
||||
fsf2([0, 1, 2, 3]),
|
||||
|
||||
fsf1([2, 4, 6, 8]),
|
||||
fsf2([2, 4, 6, 8])
|
||||
]
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
var f1 = function (x) { return x * 2; },
|
||||
f2 = function (x) { return x * x; },
|
||||
|
||||
fs = function (f) {
|
||||
return function () {
|
||||
return Array.prototype.slice.call(
|
||||
arguments
|
||||
).map(f);
|
||||
}
|
||||
},
|
||||
|
||||
fsf1 = fs(f1),
|
||||
fsf2 = fs(f2);
|
||||
|
||||
// Test alternative approach, with arbitrary numbers of arguments
|
||||
[
|
||||
fsf1(0, 1, 2, 3, 4),
|
||||
fsf2(0, 1, 2),
|
||||
fsf1(2, 4, 6, 8, 10, 12),
|
||||
fsf2(2, 4, 6, 8)
|
||||
]
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
// GENERIC FUNCTIONS ------------------------------------------------------
|
||||
|
||||
// curry :: ((a, b) -> c) -> a -> b -> c
|
||||
const curry = f => a => b => f(a, b);
|
||||
|
||||
// map :: (a -> b) -> [a] -> [b]
|
||||
const map = curry((f, xs) => xs.map(f));
|
||||
|
||||
|
||||
// PARTIAL APPLICATION ----------------------------------------------------
|
||||
|
||||
const
|
||||
f1 = x => x * 2,
|
||||
f2 = x => x * x,
|
||||
|
||||
fs = map,
|
||||
|
||||
fsf1 = fs(f1),
|
||||
fsf2 = fs(f2);
|
||||
|
||||
// TEST -------------------------------------------------------------------
|
||||
return [
|
||||
fsf1([0, 1, 2, 3]),
|
||||
fsf2([0, 1, 2, 3]),
|
||||
|
||||
fsf1([2, 4, 6, 8]),
|
||||
fsf2([2, 4, 6, 8])
|
||||
];
|
||||
})();
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
// GENERIC FUNCTIONS ------------------------------------------------------
|
||||
|
||||
// 2 or more arguments
|
||||
// curry :: Function -> Function
|
||||
const curry = (f, ...args) => {
|
||||
const go = xs => xs.length >= f.length ? (f.apply(null, xs)) :
|
||||
function () {
|
||||
return go(xs.concat(Array.from(arguments)));
|
||||
};
|
||||
return go([].slice.call(args, 1));
|
||||
};
|
||||
|
||||
// map :: (a -> b) -> [a] -> [b]
|
||||
const map = curry((f, xs) => xs.map(f));
|
||||
|
||||
// PARTIAL APPLICATION ----------------------------------------------------
|
||||
const
|
||||
f1 = x => x * 2,
|
||||
f2 = x => x * x,
|
||||
|
||||
fs = map,
|
||||
|
||||
fsf1 = fs(f1),
|
||||
fsf2 = fs(f2);
|
||||
|
||||
// TEST -------------------------------------------------------------------
|
||||
return [
|
||||
fsf1([0, 1, 2, 3]),
|
||||
fsf2([0, 1, 2, 3]),
|
||||
|
||||
fsf1([2, 4, 6, 8]),
|
||||
fsf2([2, 4, 6, 8])
|
||||
];
|
||||
})();
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# fs(f, s) takes a function, f, of one value and a sequence of values s,
|
||||
# and returns an ordered sequence of the result of applying function f to every value of s in turn.
|
||||
|
||||
def fs(f; s): s | f;
|
||||
|
||||
# f1 takes a value and returns it multiplied by 2:
|
||||
def f1: 2 * .;
|
||||
|
||||
# f2 takes a value and returns it squared:
|
||||
def f2: . * .;
|
||||
|
||||
# Partially apply f1 to fs to form function fsf1(s):
|
||||
def fsf1(s): fs(f1;s);
|
||||
|
||||
# Partially apply f2 to fs to form function fsf2(s)
|
||||
def fsf2(s): fs(f2; s);
|
||||
|
||||
# Test fsf1 and fsf2 by evaluating them with s being the sequence of integers from 0 to 3 inclusive ...
|
||||
|
||||
"fsf1",
|
||||
[fsf1(range(0;4))],
|
||||
"fsf2",
|
||||
[fsf2(range(0;4))],
|
||||
|
||||
# and then the sequence of even integers from 2 to 8 inclusive:
|
||||
|
||||
"fsf1",
|
||||
[fsf1(range(2;9;2))],
|
||||
"fsf2",
|
||||
[fsf2(range(2;9;2))]
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
fs(f, s) = map(f, s)
|
||||
f1(x) = 2x
|
||||
f2(x) = x^2
|
||||
fsf1(s) = fs(f1, s)
|
||||
fsf2(s) = fs(f2, s)
|
||||
|
||||
s1 = [0, 1, 2 ,3]
|
||||
s2 = [2, 4, 6, 8]
|
||||
println("fsf1 of s1 is $(fsf1(s1))")
|
||||
println("fsf2 of s1 is $(fsf2(s1))")
|
||||
println("fsf1 of s2 is $(fsf1(s2))")
|
||||
println("fsf2 of s2 is $(fsf2(s2))")
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// version 1.1.2
|
||||
|
||||
typealias Func = (Int) -> Int
|
||||
typealias FuncS = (Func, List<Int>) -> List<Int>
|
||||
|
||||
fun fs(f: Func, seq: List<Int>) = seq.map { f(it) }
|
||||
|
||||
fun partial(fs: FuncS, f: Func) = { seq: List<Int> -> fs(f, seq) }
|
||||
|
||||
fun f1(n: Int) = 2 * n
|
||||
|
||||
fun f2(n: Int) = n * n
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val fsf1 = partial(::fs, ::f1)
|
||||
val fsf2 = partial(::fs, ::f2)
|
||||
val seqs = listOf(
|
||||
listOf(0, 1, 2, 3),
|
||||
listOf(2, 4, 6, 8)
|
||||
)
|
||||
for (seq in seqs) {
|
||||
println(fs(::f1, seq)) // normal
|
||||
println(fsf1(seq)) // partial
|
||||
println(fs(::f2, seq)) // normal
|
||||
println(fsf2(seq)) // partial
|
||||
println()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
(defun partial
|
||||
"The partial function is arity 2 where the first parameter must be a
|
||||
function and the second parameter may either be a single item or a list of
|
||||
items.
|
||||
|
||||
When funcall is called against the result of the partial call, a second
|
||||
parameter is applied to the partial function. This parameter too may be
|
||||
either a single item or a list of items."
|
||||
((func args-1) (when (is_list args-1))
|
||||
(match-lambda
|
||||
((args-2) (when (is_list args-2))
|
||||
(apply func (++ args-1 args-2)))
|
||||
((arg-2)
|
||||
(apply func (++ args-1 `(,arg-2))))))
|
||||
((func arg-1)
|
||||
(match-lambda
|
||||
((args-2) (when (is_list args-2))
|
||||
(apply func (++ `(,arg-1) args-2)))
|
||||
((arg-2)
|
||||
(funcall func arg-1 arg-2)))))
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
(defun fs (f s) (lists:map f s))
|
||||
(defun f1 (i) (* i 2))
|
||||
(defun f2 (i) (math:pow i 2))
|
||||
|
||||
(set fsf1 (partial #'fs/2 #'f1/1))
|
||||
(set fsf2 (partial #'fs/2 #'f2/1))
|
||||
(set seq1 '((0 1 2 3)))
|
||||
(set seq2 '((2 4 6 8)))
|
||||
|
||||
> (funcall fsf1 seq1)
|
||||
(0 2 4 6)
|
||||
> (funcall fsf2 seq1)
|
||||
(0.0 1.0 4.0 9.0)
|
||||
> (funcall fsf1 seq2)
|
||||
(4 8 12 16)
|
||||
> (funcall fsf2 seq2)
|
||||
(4.0 16.0 36.0 64.0)
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
1) just define function as usual:
|
||||
{def add {lambda {:a :b :c} {+ :a :b :c}}} -> add
|
||||
|
||||
2) and use it:
|
||||
{add 1 2 3} -> 6
|
||||
{{add 1} 2 3} -> 6
|
||||
{{add 1 2} 3} -> 6
|
||||
{{{add 1} 2} 3} -> 6
|
||||
|
||||
3) application:
|
||||
{def fs {lambda {:f} map :f}}
|
||||
{def f1 {lambda {:x} {* :x 2}}}
|
||||
{def f2 {lambda {:x} {pow :x 2}}}
|
||||
{def fsf1 {fs f1}}
|
||||
{def fsf2 {fs f2}}
|
||||
|
||||
{{fsf1} 0 1 2 3}
|
||||
{{fsf2} 0 1 2 3}
|
||||
{{fsf1} 2 4 6 8}
|
||||
{{fsf2} 2 4 6 8}
|
||||
|
||||
Output:
|
||||
0 2 4 6
|
||||
0 1 4 9
|
||||
4 8 12 16
|
||||
4 16 36 64
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
:- object(partial_functions).
|
||||
|
||||
:- public(show/0).
|
||||
|
||||
show :-
|
||||
% create the partial functions
|
||||
create_partial_function(f1, PF1),
|
||||
create_partial_function(f2, PF2),
|
||||
% apply the partial functions
|
||||
Sequence1 = [0,1,2,3],
|
||||
call(PF1, Sequence1, PF1Sequence1), output_results(PF1, Sequence1, PF1Sequence1),
|
||||
call(PF2, Sequence1, PF2Sequence1), output_results(PF2, Sequence1, PF2Sequence1),
|
||||
Sequence2 = [2,4,6,8],
|
||||
call(PF1, Sequence2, PF1Sequence2), output_results(PF1, Sequence2, PF1Sequence2),
|
||||
call(PF2, Sequence2, PF2Sequence2), output_results(PF2, Sequence2, PF2Sequence2).
|
||||
|
||||
create_partial_function(Closure, fs(Closure)).
|
||||
|
||||
output_results(Function, Input, Output) :-
|
||||
write(Input), write(' -> '), write(Function), write(' -> '), write(Output), nl.
|
||||
|
||||
fs(Closure, Arg1, Arg2) :-
|
||||
meta::map(Closure, Arg1, Arg2).
|
||||
|
||||
f1(Value, Double) :-
|
||||
Double is 2*Value.
|
||||
|
||||
f2(Value, Square) :-
|
||||
Square is Value*Value.
|
||||
|
||||
:- end_object.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
| ?- partial_functions::show.
|
||||
[0,1,2,3] -> fs(f1) -> [0,2,4,6]
|
||||
[0,1,2,3] -> fs(f2) -> [0,1,4,9]
|
||||
[2,4,6,8] -> fs(f1) -> [4,8,12,16]
|
||||
[2,4,6,8] -> fs(f2) -> [4,16,36,64]
|
||||
yes
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
function map(f, ...)
|
||||
local t = {}
|
||||
for k, v in ipairs(...) do
|
||||
t[#t+1] = f(v)
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
function timestwo(n)
|
||||
return n * 2
|
||||
end
|
||||
|
||||
function squared(n)
|
||||
return n ^ 2
|
||||
end
|
||||
|
||||
function partial(f, arg)
|
||||
return function(...)
|
||||
return f(arg, ...)
|
||||
end
|
||||
end
|
||||
|
||||
timestwo_s = partial(map, timestwo)
|
||||
squared_s = partial(map, squared)
|
||||
|
||||
print(table.concat(timestwo_s{0, 1, 2, 3}, ', '))
|
||||
print(table.concat(squared_s{0, 1, 2, 3}, ', '))
|
||||
print(table.concat(timestwo_s{2, 4, 6, 8}, ', '))
|
||||
print(table.concat(squared_s{2, 4, 6, 8}, ', '))
|
||||
|
|
@ -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,10 @@
|
|||
'map :fs
|
||||
(dup +) :f1
|
||||
(dup *) :f2
|
||||
('f1 fs) :fsf1
|
||||
('f2 fs) :fsf2
|
||||
|
||||
(0 1 2 3) fsf1 puts!
|
||||
(0 1 2 3) fsf2 puts!
|
||||
(2 4 6 8) fsf1 puts!
|
||||
(2 4 6 8) fsf2 puts!
|
||||
|
|
@ -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,28 @@
|
|||
import sequtils
|
||||
|
||||
type
|
||||
|
||||
Func = proc(n: int): int
|
||||
FuncS = proc(f: Func; s: seq[int]): seq[int]
|
||||
|
||||
proc fs(f: Func; s: seq[int]): seq[int] = s.map(f)
|
||||
|
||||
proc partial(fs: FuncS; f: Func): auto =
|
||||
result = proc(s: seq[int]): seq[int] = fs(f, s)
|
||||
|
||||
proc f1(n: int): int = 2 * n
|
||||
proc f2(n: int): int = n * n
|
||||
|
||||
when isMainModule:
|
||||
|
||||
const Seqs = @[@[0, 1, 2, 3], @[2, 4, 6, 8]]
|
||||
|
||||
let fsf1 = partial(fs, f1)
|
||||
let fsf2 = partial(fs, f2)
|
||||
|
||||
for s in Seqs:
|
||||
echo fs(f1, s) # Normal.
|
||||
echo fsf1(s) # Partial.
|
||||
echo fs(f2, s) # Normal.
|
||||
echo fsf2(s) # Partial.
|
||||
echo ""
|
||||
|
|
@ -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,6 @@
|
|||
: fs(s, f) f s map ;
|
||||
: f1 2 * ;
|
||||
: f2 sq ;
|
||||
|
||||
#f1 #fs curry => fsf1
|
||||
#f2 #fs curry => fsf2
|
||||
|
|
@ -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,9 @@
|
|||
fs=apply;
|
||||
f1(x)=2*x;
|
||||
f2(x)=x^2;
|
||||
fsf1=any->=fs(f1,any);
|
||||
fsf2=any->=fs(f2,any);
|
||||
fsf1([0..3])
|
||||
fsf1(2([1..4])
|
||||
fsf2([0..3])
|
||||
fsf2(2([1..4])
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
sub fs :prototype(&) {
|
||||
my $func = shift;
|
||||
sub { map $func->($_), @_ }
|
||||
}
|
||||
|
||||
sub double :prototype($) { shift() * 2 }
|
||||
sub square :prototype($) { 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,26 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">fs</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">rid</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rid</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">r</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">p_apply</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">args</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">f1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f2</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">f</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">f1</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">args</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">f1</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">i</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">f2</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">*</span><span style="color: #000000;">i</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%v\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">p_apply</span><span style="color: #0000FF;">({</span><span style="color: #000000;">fs</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f1</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">})})</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%v\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">p_apply</span><span style="color: #0000FF;">({</span><span style="color: #000000;">fs</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f2</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">})})</span>
|
||||
<!--
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">fs</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">rid</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rid</span><span style="color: #0000FF;">(</span><span style="color: #000000;">j</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">r</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">p_apply</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">ffa</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">args</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">f1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ffa</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">f1</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">,</span><span style="color: #000000;">args</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">f3</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">+</span><span style="color: #000000;">i</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%v\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">p_apply</span><span style="color: #0000FF;">({</span><span style="color: #000000;">fs</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">})})</span>
|
||||
<!--
|
||||
|
|
@ -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,31 @@
|
|||
[ [] unrot
|
||||
swap nested
|
||||
' join nested
|
||||
join nested
|
||||
' witheach nested
|
||||
swap join
|
||||
do ] is fs ( f s --> [ )
|
||||
|
||||
[ 2 * ] is f1 ( n --> n )
|
||||
|
||||
[ 2 ** ] is f2 ( n --> n )
|
||||
|
||||
[ ' f1 swap fs ] is fsf1 ( s --> [ )
|
||||
|
||||
[ ' f2 swap fs ] is fsf2 ( s --> [ )
|
||||
|
||||
' [ 0 1 2 3 ] fsf1 echo cr
|
||||
' [ 0 1 2 3 ] fsf2 echo cr
|
||||
' [ 2 4 6 8 ] fsf1 echo cr
|
||||
' [ 2 4 6 8 ] fsf2 echo cr
|
||||
|
||||
( ... or, using Quackery's partial applicator "witheach",
|
||||
which applies the word or nest following it to each
|
||||
item in a nest on the top of the stack ... )
|
||||
|
||||
cr
|
||||
|
||||
' [ [ 0 1 2 3 ] [ 2 4 6 8 ] ]
|
||||
witheach
|
||||
[ dup ' [ fsf1 fsf2 ]
|
||||
witheach [ do echo cr ] ]
|
||||
|
|
@ -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,23 @@
|
|||
/*REXX program demonstrates a method of a partial function application. */
|
||||
s=; do a=0 to 3 /*build 1st series of some low integers*/
|
||||
s=strip(s a) /*append to the integer to the S list*/
|
||||
end /*a*/
|
||||
|
||||
call fs 'f1',s; say 'for f1: series=' s", result=" result
|
||||
call fs 'f2',s; say 'for f2: series=' s", result=" result
|
||||
|
||||
s=; do b=2 to 8 by 2 /*build 2nd series, low even integers. */
|
||||
s=strip(s b) /*append to the integer to the S list*/
|
||||
end /*b*/
|
||||
|
||||
call fs 'f1',s; say 'for f1: series=' s", result=" result
|
||||
call fs 'f2',s; say 'for f2: series=' s", result=" result
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*────────────────────────────────────────────────────────────────────────────*/
|
||||
f1: return arg(1)* 2
|
||||
f2: return arg(1)**2
|
||||
/*────────────────────────────────────────────────────────────────────────────*/
|
||||
fs: procedure; arg f,s; $=; do j=1 for words(s); z=word(s,j)
|
||||
interpret '$=$' f"("z')'
|
||||
end /*j*/
|
||||
return strip($)
|
||||
|
|
@ -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,11 @@
|
|||
sub fs ( Code $f, @s ) { @s.map: { .$f } }
|
||||
|
||||
sub f1 ( $n ) { $n * 2 }
|
||||
sub f2 ( $n ) { $n ** 2 }
|
||||
|
||||
my &fsf1 := &fs.assuming(&f1);
|
||||
my &fsf2 := &fs.assuming(&f2);
|
||||
|
||||
for [1..3], [2, 4 ... 8] X &fsf1, &fsf2 -> ($s, $f) {
|
||||
say $f.($s);
|
||||
}
|
||||
|
|
@ -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,10 @@
|
|||
def fs[X](f:X=>X)(s:Seq[X]) = s map f
|
||||
def f1(x:Int) = x * 2
|
||||
def f2(x:Int) = x * x
|
||||
|
||||
def fsf[X](f:X=>X) = fs(f) _
|
||||
val fsf1 = fsf(f1) // or without the fsf intermediary: val fsf1 = fs(f1) _
|
||||
val fsf2 = fsf(f2) // or without the fsf intermediary: val fsf2 = fs(f2) _
|
||||
|
||||
assert(fsf1(List(0,1,2,3)) == List(0,2,4,6))
|
||||
assert(fsf2(List(0,1,2,3)) == List(0,1,4,9))
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
func fs(f) {
|
||||
func(*args) {
|
||||
args.map {f(_)}
|
||||
}
|
||||
}
|
||||
|
||||
func double(n) { n * 2 };
|
||||
func square(n) { n ** 2 };
|
||||
|
||||
var fs_double = fs(double);
|
||||
var fs_square = fs(square);
|
||||
|
||||
var s = (0 .. 3);
|
||||
say "fs_double(#{s}): #{fs_double(s...)}";
|
||||
say "fs_square(#{s}): #{fs_square(s...)}";
|
||||
|
||||
s = [2, 4, 6, 8];
|
||||
say "fs_double(#{s}): #{fs_double(s...)}";
|
||||
say "fs_square(#{s}): #{fs_square(s...)}";
|
||||
|
|
@ -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,5 @@
|
|||
$ txr -p "(mapcar (op mapcar (op * 2)) (list (range 0 3) (range 2 8 2)))"
|
||||
((0 2 4 6) (4 8 12 16))
|
||||
|
||||
$ txr -p "(mapcar (op mapcar (op * @1 @1)) (list (range 0 3) (range 2 8 2)))"
|
||||
((0 1 4 9) (4 16 36 64))
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
$ txr -e "(progn
|
||||
(defun fs (fun seq) (mapcar fun seq))
|
||||
(defun f1 (num) (* 2 num))
|
||||
(defun f2 (num) (* num num))
|
||||
(defvar fsf1 (op fs f1)) ;; pointless: can just be (defun fsf1 (seq) (fs f1 seq)) !!!
|
||||
(defvar fsf2 (op fs f2))
|
||||
|
||||
(print [fs fsf1 '((0 1 2 3) (2 4 6 8))]) (put-line \"\")
|
||||
(print [fs fsf2 '((0 1 2 3) (2 4 6 8))]) (put-line \"\"))"
|
||||
((0 2 4 6) (4 8 12 16))
|
||||
((0 1 4 9) (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]"
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
Module PartialApplication
|
||||
Function fs(Of TSource, TResult)(f As Func(Of TSource, TResult), s As IEnumerable(Of TSource)) As IEnumerable(Of TResult)
|
||||
' This is exactly what Enumerable.Select does.
|
||||
Return s.Select(f)
|
||||
End Function
|
||||
|
||||
Function f1(x As Integer) As Integer
|
||||
Return x * 2
|
||||
End Function
|
||||
|
||||
Function f2(x As Integer) As Integer
|
||||
Return x * x
|
||||
End Function
|
||||
|
||||
' The overload that takes a binary function and partially applies to its first parameter.
|
||||
Function PartialApply(Of T1, T2, TResult)(f As Func(Of T1, T2, TResult), arg As T1) As Func(Of T2, TResult)
|
||||
Return Function(arg2) f(arg, arg2)
|
||||
End Function
|
||||
|
||||
Sub Main()
|
||||
Dim args1 As Integer() = {0, 1, 2, 3}
|
||||
Dim args2 As Integer() = {2, 4, 6, 8}
|
||||
|
||||
Dim fsf1 = PartialApply(Of Func(Of Integer, Integer), IEnumerable(Of Integer), IEnumerable(Of Integer))(AddressOf fs, AddressOf f1)
|
||||
Dim fsf2 = PartialApply(Of Func(Of Integer, Integer), IEnumerable(Of Integer), IEnumerable(Of Integer))(AddressOf fs, AddressOf f2)
|
||||
|
||||
Console.WriteLine("fsf1, 0-3: " & String.Join(", ", fsf1(args1)))
|
||||
Console.WriteLine("fsf1, evens: " & String.Join(", ", fsf1(args2)))
|
||||
Console.WriteLine("fsf2, 0-3: " & String.Join(", ", fsf2(args1)))
|
||||
Console.WriteLine("fsf2, evens: " & String.Join(", ", fsf2(args2)))
|
||||
End Sub
|
||||
End Module
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
Option Strict Off
|
||||
|
||||
Partial Module PartialApplicationDynamic
|
||||
Function f1(x As Object) As Object
|
||||
Return x * 2
|
||||
End Function
|
||||
|
||||
Function f2(x As Object) As Object
|
||||
Return x * x
|
||||
End Function
|
||||
End Module
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
Option Strict On
|
||||
|
||||
Partial Module PartialApplicationDynamic
|
||||
' Create a matching delegate type to simplify delegate creation.
|
||||
Delegate Function fsDelegate(Of TSource, TResult)(f As Func(Of TSource, TResult), s As IEnumerable(Of TSource)) As IEnumerable(Of TResult)
|
||||
Function fs(Of TSource, TResult)(f As Func(Of TSource, TResult), s As IEnumerable(Of TSource)) As IEnumerable(Of TResult)
|
||||
' This is exactly what Enumerable.Select does.
|
||||
Return s.Select(f)
|
||||
End Function
|
||||
|
||||
Function ArrayConcat(Of T)(arr1 As T(), arr2 As T()) As T()
|
||||
Dim result(arr1.Length + arr2.Length - 1) As T
|
||||
Array.Copy(arr1, result, arr1.Length)
|
||||
Array.Copy(arr2, 0, result, 1, arr2.Length)
|
||||
Return result
|
||||
End Function
|
||||
|
||||
' C# can define ParamArray delegates and VB can consume them, but VB cannot define them on its own.
|
||||
' The argument list of calls to the resulting function thus must be wrapped in a coerced array literal.
|
||||
' VB also doesn't allow Delegate as a type constraint. :(
|
||||
' The function is generic solely to ease use for callers. In this case generics aren't providing any type-safety.
|
||||
Function PartialApplyDynamic(Of TDelegate, TResult)(f As TDelegate, ParamArray args As Object()) As Func(Of Object(), TResult)
|
||||
Dim del = CType(CObj(f), [Delegate])
|
||||
Return Function(rest) CType(del.DynamicInvoke(ArrayConcat(args, rest).Cast(Of Object).ToArray()), TResult)
|
||||
End Function
|
||||
|
||||
Sub Main()
|
||||
Dim args1 As Object = New Object() {0, 1, 2, 3}
|
||||
Dim args2 As Object = New Object() {2, 4, 6, 8}
|
||||
|
||||
Dim fsf1 = PartialApplyDynamic(Of fsDelegate(Of Object, Object), IEnumerable(Of Object))(AddressOf fs, New Func(Of Object, Object)(AddressOf f1))
|
||||
Dim fsf2 = PartialApplyDynamic(Of fsDelegate(Of Object, Object), IEnumerable(Of Object))(AddressOf fs, New Func(Of Object, Object)(AddressOf f2))
|
||||
|
||||
' The braces are array literals.
|
||||
Console.WriteLine("fsf1, 0-3: " & String.Join(", ", fsf1({args1})))
|
||||
Console.WriteLine("fsf1, evens: " & String.Join(", ", fsf1({args2})))
|
||||
Console.WriteLine("fsf2, 0-3: " & String.Join(", ", fsf2({args1})))
|
||||
Console.WriteLine("fsf2, evens: " & String.Join(", ", fsf2({args2})))
|
||||
End Sub
|
||||
End Module
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
var fs = Fn.new { |f, s| s.map { |e| f.call(e) }.toList }
|
||||
var f1 = Fn.new { |n| 2 * n }
|
||||
var f2 = Fn.new { |n| n * n }
|
||||
|
||||
var partial = Fn.new { |f, g| Fn.new { |x| f.call(g, x) } }
|
||||
|
||||
var ss = [[0, 1, 2, 3], [2, 4, 6, 8]]
|
||||
for (s in ss) {
|
||||
var fsf1 = partial.call(fs, f1)
|
||||
var fsf2 = partial.call(fs, f2)
|
||||
System.print(fsf1.call(s))
|
||||
System.print(fsf2.call(s))
|
||||
System.print()
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
func_fs:
|
||||
;input
|
||||
;hl = function to call
|
||||
;ix = data range to operate over
|
||||
;de = output area
|
||||
;b = length of data range
|
||||
|
||||
push bc
|
||||
ld (smc_fs+1),hl
|
||||
ld a,(ix+0)
|
||||
smc_fs:
|
||||
call 0 ;overwritten with the function address passed in HL
|
||||
|
||||
ld (de),a
|
||||
inc ix
|
||||
inc de
|
||||
pop bc
|
||||
djnz func_fs
|
||||
ret
|
||||
|
||||
f: ;dummy function - returns input as-is
|
||||
ret
|
||||
|
||||
f1:
|
||||
;returns A times 2
|
||||
sla a
|
||||
ret
|
||||
|
||||
f2:
|
||||
;returns A squared
|
||||
ld b,a
|
||||
jp square_small
|
||||
;ret
|
||||
|
||||
data1:
|
||||
db 0,1,2,3
|
||||
|
||||
data2
|
||||
db 2,4,6,8
|
||||
|
||||
output:
|
||||
ds 4
|
||||
|
||||
;these libraries allow us to write the output to the screen
|
||||
read "\SrcCPC\winape_monitor.asm"
|
||||
read "\SrcCPC\winape_stringop.asm"
|
||||
read "\SrcCPC\winape_showhex.asm"
|
||||
|
||||
square_small:
|
||||
;returns a*a into a
|
||||
LD C,B
|
||||
mul8_small:
|
||||
;multiplies two 8-bit regs, product is also 8 bit.
|
||||
;no overflow protection!
|
||||
;computes A = c * b
|
||||
ld a,c
|
||||
or a
|
||||
ret z
|
||||
|
||||
djnz skip_return_C
|
||||
;ADVANCED TRICKERY:
|
||||
; we need to decrement B anyway.
|
||||
; also if B = 1, then A = C.
|
||||
; C is already in A, which we need for the multiplication regardless.
|
||||
; This does the job for us in one instruction!
|
||||
; Most DJNZs are backward but this one is FORWARD!
|
||||
ret
|
||||
skip_return_C:
|
||||
add C
|
||||
djnz skip_return_C
|
||||
ret
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
;;;;;;;;;;;;;;;;;;; HEADER ;;;;;;;;;;;;;;;;;;;
|
||||
read "\SrcCPC\winape_macros.asm"
|
||||
read "\SrcCPC\MemoryMap.asm"
|
||||
read "\SrcALL\winapeBuildCompat.asm"
|
||||
;;;;;;;;;;;;;;;;;;; PROGRAM ;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
org &1000
|
||||
|
||||
ld hl,f1
|
||||
ld ix,data1
|
||||
ld de,output
|
||||
ld b,4
|
||||
call func_fs ;execute f1f(s) on data set 1
|
||||
|
||||
|
||||
call monitor_memdump ;display the output
|
||||
db 4
|
||||
dw output
|
||||
|
||||
call newline
|
||||
|
||||
ld hl,f1
|
||||
ld ix,data2
|
||||
ld de,output
|
||||
ld b,4
|
||||
call func_fs ;;execute f1f(s) on data set 2
|
||||
|
||||
|
||||
call monitor_memdump ;display the output
|
||||
db 4
|
||||
dw output
|
||||
|
||||
call newline
|
||||
|
||||
ld hl,f2
|
||||
ld ix,data1
|
||||
ld de,output
|
||||
ld b,4
|
||||
call func_fs
|
||||
|
||||
|
||||
call monitor_memdump
|
||||
db 4
|
||||
dw output
|
||||
|
||||
call newline
|
||||
|
||||
ld hl,f2
|
||||
ld ix,data2
|
||||
ld de,output
|
||||
ld b,4
|
||||
call func_fs
|
||||
|
||||
|
||||
call monitor_memdump
|
||||
db 4
|
||||
dw output
|
||||
|
||||
ret ;return to basic
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
fcn fs(f,s){s.apply(f)} fcn f1(n){n*2} fcn f2(n){n*n}
|
||||
var fsf1=fs.fp(f1), fsf2=fs.fp(f2);
|
||||
fsf1([0..3]); //-->L(0,2,4,6)
|
||||
fsf2([2..8,2]); //-->L(4,16,36,64)
|
||||
Loading…
Add table
Add a link
Reference in a new issue