all tasks
This commit is contained in:
parent
b83f433714
commit
68f8f3e56b
14735 changed files with 178959 additions and 0 deletions
8
Task/Y-combinator/0DESCRIPTION
Normal file
8
Task/Y-combinator/0DESCRIPTION
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
In strict [[wp:Functional programming|functional programming]] and the [[wp:lambda calculus|lambda calculus]], functions (lambda expressions) don't have state and are only allowed to refer to arguments of enclosing functions. This rules out the usual definition of a recursive function wherein a function is associated with the state of a variable and this variable's state is used in the body of the function.
|
||||
|
||||
The [http://mvanier.livejournal.com/2897.html Y combinator] is itself a stateless function that, when applied to another stateless function, returns a recursive version of the function. The Y combinator is the simplest of the class of such functions, called [[wp:Fixed-point combinator|fixed-point combinators]].
|
||||
|
||||
The task is to define the stateless Y combinator and use it to compute [[wp:Factorial|factorials]] and [[wp:Fibonacci number|Fibonacci numbers]] from other stateless functions or lambda expressions.
|
||||
|
||||
;Cf:
|
||||
* [http://vimeo.com/45140590 Jim Weirich: Adventures in Functional Programming]
|
||||
6
Task/Y-combinator/1META.yaml
Normal file
6
Task/Y-combinator/1META.yaml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
category:
|
||||
- Recursion
|
||||
note: Classic CS problems and programs
|
||||
requires:
|
||||
- First class functions
|
||||
11
Task/Y-combinator/ALGOL-68/y-combinator.alg
Normal file
11
Task/Y-combinator/ALGOL-68/y-combinator.alg
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
BEGIN
|
||||
MODE F = PROC(INT)INT;
|
||||
MODE Y = PROC(Y)F;
|
||||
|
||||
# compare python Y = lambda f: (lambda x: x(x)) (lambda y: f( lambda *args: y(y)(*args)))#
|
||||
PROC y = (PROC(F)F f)F: ( (Y x)F: x(x)) ( (Y z)F: f((INT arg )INT: z(z)( arg )));
|
||||
|
||||
PROC fib = (F f)F: (INT n)INT: CASE n IN n,n OUT f(n-1) + f(n-2) ESAC;
|
||||
|
||||
FOR i TO 10 DO print(y(fib)(i)) OD
|
||||
END
|
||||
54
Task/Y-combinator/AppleScript/y-combinator.applescript
Normal file
54
Task/Y-combinator/AppleScript/y-combinator.applescript
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
to |Y|(f)
|
||||
script x
|
||||
to funcall(y)
|
||||
script
|
||||
to funcall(arg)
|
||||
y's funcall(y)'s funcall(arg)
|
||||
end funcall
|
||||
end script
|
||||
f's funcall(result)
|
||||
end funcall
|
||||
end script
|
||||
x's funcall(x)
|
||||
end |Y|
|
||||
|
||||
script
|
||||
to funcall(f)
|
||||
script
|
||||
to funcall(n)
|
||||
if n = 0 then return 1
|
||||
n * (f's funcall(n - 1))
|
||||
end funcall
|
||||
end script
|
||||
end funcall
|
||||
end script
|
||||
set fact to |Y|(result)
|
||||
|
||||
script
|
||||
to funcall(f)
|
||||
script
|
||||
to funcall(n)
|
||||
if n = 0 then return 0
|
||||
if n = 1 then return 1
|
||||
(f's funcall(n - 2)) + (f's funcall(n - 1))
|
||||
end funcall
|
||||
end script
|
||||
end funcall
|
||||
end script
|
||||
set fib to |Y|(result)
|
||||
|
||||
set facts to {}
|
||||
repeat with i from 0 to 11
|
||||
set end of facts to fact's funcall(i)
|
||||
end repeat
|
||||
|
||||
set fibs to {}
|
||||
repeat with i from 0 to 20
|
||||
set end of fibs to fib's funcall(i)
|
||||
end repeat
|
||||
|
||||
{facts:facts, fibs:fibs}
|
||||
(*
|
||||
{facts:{1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800},
|
||||
fibs:{0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765}}
|
||||
*)
|
||||
156
Task/Y-combinator/BlitzMax/y-combinator.blitz
Normal file
156
Task/Y-combinator/BlitzMax/y-combinator.blitz
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
SuperStrict
|
||||
|
||||
'Boxed type so we can just use object arrays for argument lists
|
||||
Type Integer
|
||||
Field val:Int
|
||||
Function Make:Integer(_val:Int)
|
||||
Local i:Integer = New Integer
|
||||
i.val = _val
|
||||
Return i
|
||||
End Function
|
||||
End Type
|
||||
|
||||
|
||||
'Higher-order function type - just a procedure attached to a scope
|
||||
Type Func Abstract
|
||||
Method apply:Object(args:Object[]) Abstract
|
||||
End Type
|
||||
|
||||
'Function definitions - extend with fields as locals and implement apply as body
|
||||
Type Scope Extends Func Abstract
|
||||
Field env:Scope
|
||||
|
||||
'Constructor - bind an environment to a procedure
|
||||
Function lambda:Scope(env:Scope) Abstract
|
||||
|
||||
Method _init:Scope(_env:Scope) 'Helper to keep constructors small
|
||||
env = _env ; Return Self
|
||||
End Method
|
||||
End Type
|
||||
|
||||
|
||||
'Based on the following definition:
|
||||
'(define (Y f)
|
||||
' (let ((_r (lambda (r) (f (lambda a (apply (r r) a))))))
|
||||
' (_r _r)))
|
||||
|
||||
'Y (outer)
|
||||
Type Y Extends Scope
|
||||
Field f:Func 'Parameter - gets closed over
|
||||
|
||||
Function lambda:Scope(env:Scope) 'Necessary due to highly limited constructor syntax
|
||||
Return (New Y)._init(env)
|
||||
End Function
|
||||
|
||||
Method apply:Func(args:Object[])
|
||||
f = Func(args[0])
|
||||
Local _r:Func = YInner1.lambda(Self)
|
||||
Return Func(_r.apply([_r]))
|
||||
End Method
|
||||
End Type
|
||||
|
||||
'First lambda within Y
|
||||
Type YInner1 Extends Scope
|
||||
Field r:Func 'Parameter - gets closed over
|
||||
|
||||
Function lambda:Scope(env:Scope)
|
||||
Return (New YInner1)._init(env)
|
||||
End Function
|
||||
|
||||
Method apply:Func(args:Object[])
|
||||
r = Func(args[0])
|
||||
Return Func(Y(env).f.apply([YInner2.lambda(Self)]))
|
||||
End Method
|
||||
End Type
|
||||
|
||||
'Second lambda within Y
|
||||
Type YInner2 Extends Scope
|
||||
Field a:Object[] 'Parameter - not really needed, but good for clarity
|
||||
|
||||
Function lambda:Scope(env:Scope)
|
||||
Return (New YInner2)._init(env)
|
||||
End Function
|
||||
|
||||
Method apply:Object(args:Object[])
|
||||
a = args
|
||||
Local r:Func = YInner1(env).r
|
||||
Return Func(r.apply([r])).apply(a)
|
||||
End Method
|
||||
End Type
|
||||
|
||||
|
||||
'Based on the following definition:
|
||||
'(define fac (Y (lambda (f)
|
||||
' (lambda (x)
|
||||
' (if (<= x 0) 1 (* x (f (- x 1)))))))
|
||||
|
||||
Type FacL1 Extends Scope
|
||||
Field f:Func 'Parameter - gets closed over
|
||||
|
||||
Function lambda:Scope(env:Scope)
|
||||
Return (New FacL1)._init(env)
|
||||
End Function
|
||||
|
||||
Method apply:Object(args:Object[])
|
||||
f = Func(args[0])
|
||||
Return FacL2.lambda(Self)
|
||||
End Method
|
||||
End Type
|
||||
|
||||
Type FacL2 Extends Scope
|
||||
Function lambda:Scope(env:Scope)
|
||||
Return (New FacL2)._init(env)
|
||||
End Function
|
||||
|
||||
Method apply:Object(args:Object[])
|
||||
Local x:Int = Integer(args[0]).val
|
||||
If x <= 0 Then Return Integer.Make(1) ; Else Return Integer.Make(x * Integer(FacL1(env).f.apply([Integer.Make(x - 1)])).val)
|
||||
End Method
|
||||
End Type
|
||||
|
||||
|
||||
'Based on the following definition:
|
||||
'(define fib (Y (lambda (f)
|
||||
' (lambda (x)
|
||||
' (if (< x 2) x (+ (f (- x 1)) (f (- x 2)))))))
|
||||
|
||||
Type FibL1 Extends Scope
|
||||
Field f:Func 'Parameter - gets closed over
|
||||
|
||||
Function lambda:Scope(env:Scope)
|
||||
Return (New FibL1)._init(env)
|
||||
End Function
|
||||
|
||||
Method apply:Object(args:Object[])
|
||||
f = Func(args[0])
|
||||
Return FibL2.lambda(Self)
|
||||
End Method
|
||||
End Type
|
||||
|
||||
Type FibL2 Extends Scope
|
||||
Function lambda:Scope(env:Scope)
|
||||
Return (New FibL2)._init(env)
|
||||
End Function
|
||||
|
||||
Method apply:Object(args:Object[])
|
||||
Local x:Int = Integer(args[0]).val
|
||||
If x < 2
|
||||
Return Integer.Make(x)
|
||||
Else
|
||||
Local f:Func = FibL1(env).f
|
||||
Local x1:Int = Integer(f.apply([Integer.Make(x - 1)])).val
|
||||
Local x2:Int = Integer(f.apply([Integer.Make(x - 2)])).val
|
||||
Return Integer.Make(x1 + x2)
|
||||
EndIf
|
||||
End Method
|
||||
End Type
|
||||
|
||||
|
||||
'Now test
|
||||
Local _Y:Func = Y.lambda(Null)
|
||||
|
||||
Local fac:Func = Func(_Y.apply([FacL1.lambda(Null)]))
|
||||
Print Integer(fac.apply([Integer.Make(10)])).val
|
||||
|
||||
Local fib:Func = Func(_Y.apply([FibL1.lambda(Null)]))
|
||||
Print Integer(fib.apply([Integer.Make(10)])).val
|
||||
44
Task/Y-combinator/Bracmat/y-combinator.bracmat
Normal file
44
Task/Y-combinator/Bracmat/y-combinator.bracmat
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
( ( Y
|
||||
= /(
|
||||
' ( g
|
||||
. /('(x.$g'($x'$x)))
|
||||
$ /('(x.$g'($x'$x)))
|
||||
)
|
||||
)
|
||||
)
|
||||
& ( g
|
||||
= /(
|
||||
' ( r
|
||||
. /(
|
||||
' ( n
|
||||
. $n:~>0&1
|
||||
| $n*($r)$($n+-1)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
& ( h
|
||||
= /(
|
||||
' ( r
|
||||
. /(
|
||||
' ( n
|
||||
. $n:(1|2)&1
|
||||
| ($r)$($n+-1)+($r)$($n+-2)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
& 0:?i
|
||||
& whl
|
||||
' ( 1+!i:~>10:?i
|
||||
& out$(str$(!i "!=" (!Y$!g)$!i))
|
||||
)
|
||||
& 0:?i
|
||||
& whl
|
||||
' ( 1+!i:~>10:?i
|
||||
& out$(str$("fib(" !i ")=" (!Y$!h)$!i))
|
||||
)
|
||||
&
|
||||
)
|
||||
43
Task/Y-combinator/C++/y-combinator.cpp
Normal file
43
Task/Y-combinator/C++/y-combinator.cpp
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#include <iostream>
|
||||
#include <functional>
|
||||
|
||||
template <typename F>
|
||||
struct RecursiveFunc {
|
||||
std::function<F(RecursiveFunc)> o;
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
std::function<B(A)> fix (std::function<std::function<B(A)>(std::function<B(A)>)> f) {
|
||||
RecursiveFunc<std::function<B(A)>> r = {
|
||||
std::function<std::function<B(A)>(RecursiveFunc<std::function<B(A)>>)>([f](RecursiveFunc<std::function<B(A)>> w) {
|
||||
return f(std::function<B(A)>([w](A x) {
|
||||
return w.o(w)(x);
|
||||
}));
|
||||
})
|
||||
};
|
||||
return r.o(r);
|
||||
}
|
||||
|
||||
typedef std::function<int(int)> Func;
|
||||
typedef std::function<Func(Func)> FuncFunc;
|
||||
FuncFunc almost_fac = [](Func f) {
|
||||
return Func([f](int n) {
|
||||
if (n <= 1) return 1;
|
||||
return n * f(n - 1);
|
||||
});
|
||||
};
|
||||
|
||||
FuncFunc almost_fib = [](Func f) {
|
||||
return Func([f](int n) {
|
||||
if (n <= 2) return 1;
|
||||
return f(n - 1) + f(n - 2);
|
||||
});
|
||||
};
|
||||
|
||||
int main() {
|
||||
auto fib = fix(almost_fib);
|
||||
auto fac = fix(almost_fac);
|
||||
std::cout << "fib(10) = " << fib(10) << std::endl;
|
||||
std::cout << "fac(10) = " << fac(10) << std::endl;
|
||||
return 0;
|
||||
}
|
||||
79
Task/Y-combinator/C/y-combinator.c
Normal file
79
Task/Y-combinator/C/y-combinator.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* func: our one and only data type; it holds either a pointer to
|
||||
a function call, or an integer. Also carry a func pointer to
|
||||
a potential parameter, to simulate closure */
|
||||
typedef struct func_t *func;
|
||||
typedef struct func_t {
|
||||
func (*func) (func, func), _;
|
||||
int num;
|
||||
} func_t;
|
||||
|
||||
func new(func(*f)(func, func), func _) {
|
||||
func x = malloc(sizeof(func_t));
|
||||
x->func = f;
|
||||
x->_ = _; /* closure, sort of */
|
||||
x->num = 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
func call(func f, func g) {
|
||||
return f->func(f, g);
|
||||
}
|
||||
|
||||
func Y(func(*f)(func, func)) {
|
||||
func _(func x, func y) { return call(x->_, y); }
|
||||
func_t __ = { _ };
|
||||
|
||||
func g = call(new(f, 0), &__);
|
||||
g->_ = g;
|
||||
return g;
|
||||
}
|
||||
|
||||
func num(int n) {
|
||||
func x = new(0, 0);
|
||||
x->num = n;
|
||||
return x;
|
||||
}
|
||||
|
||||
func fac(func f, func _null) {
|
||||
func _(func self, func n) {
|
||||
int nn = n->num;
|
||||
return nn > 1 ? num(nn * call(self->_, num(nn - 1))->num)
|
||||
: num(1);
|
||||
}
|
||||
|
||||
return new(_, f);
|
||||
}
|
||||
|
||||
func fib(func f, func _null) {
|
||||
func _(func self, func n) {
|
||||
int nn = n->num;
|
||||
return nn > 1
|
||||
? num( call(self->_, num(nn - 1))->num +
|
||||
call(self->_, num(nn - 2))->num )
|
||||
: num(1);
|
||||
}
|
||||
|
||||
return new(_, f);
|
||||
}
|
||||
|
||||
void show(func n) { printf(" %d", n->num); }
|
||||
|
||||
int main() {
|
||||
int i;
|
||||
func f = Y(fac);
|
||||
printf("fac: ");
|
||||
for (i = 1; i < 10; i++)
|
||||
show( call(f, num(i)) );
|
||||
printf("\n");
|
||||
|
||||
f = Y(fib);
|
||||
printf("fib: ");
|
||||
for (i = 1; i < 10; i++)
|
||||
show( call(f, num(i)) );
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
19
Task/Y-combinator/Clojure/y-combinator-1.clj
Normal file
19
Task/Y-combinator/Clojure/y-combinator-1.clj
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
(defn Y [f]
|
||||
((fn [x] (x x))
|
||||
(fn [x]
|
||||
(f (fn [& args]
|
||||
(apply (x x) args))))))
|
||||
|
||||
(def fac
|
||||
(fn [f]
|
||||
(fn [n]
|
||||
(if (zero? n) 1 (* n (f (dec n)))))))
|
||||
|
||||
(def fib
|
||||
(fn [f]
|
||||
(fn [n]
|
||||
(condp = n
|
||||
0 0
|
||||
1 1
|
||||
(+ (f (dec n))
|
||||
(f (dec (dec n))))))))
|
||||
2
Task/Y-combinator/Clojure/y-combinator-2.clj
Normal file
2
Task/Y-combinator/Clojure/y-combinator-2.clj
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
(defn Y [f]
|
||||
(#(% %) #(f (fn [& args] (apply (% %) args)))))
|
||||
25
Task/Y-combinator/Common-Lisp/y-combinator.lisp
Normal file
25
Task/Y-combinator/Common-Lisp/y-combinator.lisp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
(defun Y (f)
|
||||
((lambda (x) (funcall x x))
|
||||
(lambda (y)
|
||||
(funcall f (lambda (&rest args)
|
||||
(apply (funcall y y) args))))))
|
||||
|
||||
(defun fac (f)
|
||||
(lambda (n)
|
||||
(if (zerop n)
|
||||
1
|
||||
(* n (funcall f (1- n))))))
|
||||
|
||||
(defun fib (f)
|
||||
(lambda (n)
|
||||
(case n
|
||||
(0 0)
|
||||
(1 1)
|
||||
(otherwise (+ (funcall f (- n 1))
|
||||
(funcall f (- n 2)))))))
|
||||
|
||||
? ((mapcar (y #'fac) '(1 2 3 4 5 6 7 8 9 10))
|
||||
(1 2 6 24 120 720 5040 40320 362880 3628800))
|
||||
|
||||
? (mapcar (y #'fib) '(1 2 3 4 5 6 7 8 9 10))
|
||||
(1 1 2 3 5 8 13 21 34 55)
|
||||
31
Task/Y-combinator/D/y-combinator.d
Normal file
31
Task/Y-combinator/D/y-combinator.d
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import std.stdio, std.traits, std.algorithm, std.range;
|
||||
|
||||
auto Y(F)(F f) {
|
||||
alias D = void delegate();
|
||||
alias Ret = ReturnType!(ParameterTypeTuple!F);
|
||||
alias Args = ParameterTypeTuple!(ParameterTypeTuple!F);
|
||||
|
||||
return ((Ret delegate(Args) delegate(D) x) =>
|
||||
x(cast(D)x))(
|
||||
(D y) =>
|
||||
f((Args args) =>
|
||||
(cast(Ret delegate(Args))(cast(D delegate(D))y)(y))(args)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void main() { // Demo code --------------------
|
||||
auto factorial = Y((int delegate(int) self) =>
|
||||
(int n) => 0 == n ? 1 : n * self(n - 1)
|
||||
);
|
||||
|
||||
auto ackermann = Y((ulong delegate(ulong, ulong) self) =>
|
||||
(ulong m, ulong n) {
|
||||
if (m == 0) return n + 1;
|
||||
if (n == 0) return self(m - 1, 1);
|
||||
return self(m - 1, self(m, n - 1));
|
||||
});
|
||||
|
||||
writeln("factorial: ", map!factorial(iota(10)));
|
||||
writeln("ackermann(3, 5): ", ackermann(3, 5));
|
||||
}
|
||||
67
Task/Y-combinator/Delphi/y-combinator.delphi
Normal file
67
Task/Y-combinator/Delphi/y-combinator.delphi
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
program Y;
|
||||
|
||||
{$APPTYPE CONSOLE}
|
||||
|
||||
uses
|
||||
SysUtils;
|
||||
|
||||
type
|
||||
YCombinator = class sealed
|
||||
class function Fix<T> (F: TFunc<TFunc<T, T>, TFunc<T, T>>): TFunc<T, T>; static;
|
||||
end;
|
||||
|
||||
TRecursiveFuncWrapper<T> = record // workaround required because of QC #101272 (http://qc.embarcadero.com/wc/qcmain.aspx?d=101272)
|
||||
type
|
||||
TRecursiveFunc = reference to function (R: TRecursiveFuncWrapper<T>): TFunc<T, T>;
|
||||
var
|
||||
O: TRecursiveFunc;
|
||||
end;
|
||||
|
||||
class function YCombinator.Fix<T> (F: TFunc<TFunc<T, T>, TFunc<T, T>>): TFunc<T, T>;
|
||||
var
|
||||
R: TRecursiveFuncWrapper<T>;
|
||||
begin
|
||||
R.O := function (W: TRecursiveFuncWrapper<T>): TFunc<T, T>
|
||||
begin
|
||||
Result := F (function (I: T): T
|
||||
begin
|
||||
Result := W.O (W) (I);
|
||||
end);
|
||||
end;
|
||||
Result := R.O (R);
|
||||
end;
|
||||
|
||||
|
||||
type
|
||||
IntFunc = TFunc<Integer, Integer>;
|
||||
|
||||
function AlmostFac (F: IntFunc): IntFunc;
|
||||
begin
|
||||
Result := function (N: Integer): Integer
|
||||
begin
|
||||
if N <= 1 then
|
||||
Result := 1
|
||||
else
|
||||
Result := N * F (N - 1);
|
||||
end;
|
||||
end;
|
||||
|
||||
function AlmostFib (F: TFunc<Integer, Integer>): TFunc<Integer, Integer>;
|
||||
begin
|
||||
Result := function (N: Integer): Integer
|
||||
begin
|
||||
if N <= 2 then
|
||||
Result := 1
|
||||
else
|
||||
Result := F (N - 1) + F (N - 2);
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
Fib, Fac: IntFunc;
|
||||
begin
|
||||
Fib := YCombinator.Fix<Integer> (AlmostFib);
|
||||
Fac := YCombinator.Fix<Integer> (AlmostFac);
|
||||
Writeln ('Fib(10) = ', Fib (10));
|
||||
Writeln ('Fac(10) = ', Fac (10));
|
||||
end.
|
||||
3
Task/Y-combinator/E/y-combinator-1.e
Normal file
3
Task/Y-combinator/E/y-combinator-1.e
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
def y := fn f { fn x { x(x) }(fn y { f(fn a { y(y)(a) }) }) }
|
||||
def fac := fn f { fn n { if (n<2) {1} else { n*f(n-1) } }}
|
||||
def fib := fn f { fn n { if (n == 0) {0} else if (n == 1) {1} else { f(n-1) + f(n-2) } }}
|
||||
6
Task/Y-combinator/E/y-combinator-2.e
Normal file
6
Task/Y-combinator/E/y-combinator-2.e
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
? pragma.enable("accumulator")
|
||||
? accum [] for i in 0..!10 { _.with(y(fac)(i)) }
|
||||
[1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
|
||||
|
||||
? accum [] for i in 0..!10 { _.with(y(fib)(i)) }
|
||||
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
|
||||
10
Task/Y-combinator/Ela/y-combinator.ela
Normal file
10
Task/Y-combinator/Ela/y-combinator.ela
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
fix = \f -> (\x -> & f (x x)) (\x -> & f (x x))
|
||||
|
||||
fac _ 0 = 1
|
||||
fac f n = n * f (n - 1)
|
||||
|
||||
fib _ 0 = 0
|
||||
fib _ 1 = 1
|
||||
fib f n = f (n - 1) + f (n - 2)
|
||||
|
||||
(fix fac 12, fix fib 12)
|
||||
15
Task/Y-combinator/Erlang/y-combinator.erl
Normal file
15
Task/Y-combinator/Erlang/y-combinator.erl
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
Y = fun(M) -> (fun(X) -> X(X) end)(fun (F) -> M(fun(A) -> (F(F))(A) end) end) end.
|
||||
|
||||
Fac = fun (F) ->
|
||||
fun (0) -> 1;
|
||||
(N) -> N * F(N-1)
|
||||
end
|
||||
end.
|
||||
Fib = fun(F) ->
|
||||
fun(0) -> 0;
|
||||
(1) -> 1;
|
||||
(N) -> F(N-1) + F(N-2)
|
||||
end
|
||||
end.
|
||||
(Y(Fac))(5). %% 120
|
||||
(Y(Fib))(8). %% 21
|
||||
10
Task/Y-combinator/Factor/y-combinator-1.factor
Normal file
10
Task/Y-combinator/Factor/y-combinator-1.factor
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
USING: fry kernel math ;
|
||||
IN: rosettacode.Y
|
||||
: Y ( quot -- quot )
|
||||
'[ [ dup call call ] curry @ ] dup call ; inline
|
||||
|
||||
: almost-fac ( quot -- quot )
|
||||
'[ dup zero? [ drop 1 ] [ dup 1 - @ * ] if ] ;
|
||||
|
||||
: almost-fib ( quot -- quot )
|
||||
'[ dup 2 >= [ 1 2 [ - @ ] bi-curry@ bi + ] when ] ;
|
||||
5
Task/Y-combinator/Factor/y-combinator-2.factor
Normal file
5
Task/Y-combinator/Factor/y-combinator-2.factor
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
USING: kernel tools.test rosettacode.Y ;
|
||||
IN: rosettacode.Y.tests
|
||||
|
||||
[ 120 ] [ 5 [ almost-fac ] Y call ] unit-test
|
||||
[ 8 ] [ 6 [ almost-fib ] Y call ] unit-test
|
||||
9
Task/Y-combinator/Falcon/y-combinator.falcon
Normal file
9
Task/Y-combinator/Falcon/y-combinator.falcon
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
Y = { f => {x=> {n => f(x(x))(n)}} ({x=> {n => f(x(x))(n)}}) }
|
||||
facStep = { f => {x => x < 1 ? 1 : x*f(x-1) }}
|
||||
fibStep = { f => {x => x == 0 ? 0 : (x == 1 ? 1 : f(x-1) + f(x-2))}}
|
||||
|
||||
YFac = Y(facStep)
|
||||
YFib = Y(fibStep)
|
||||
|
||||
> "Factorial 10: ", YFac(10)
|
||||
> "Fibonacci 10: ", YFib(10)
|
||||
35
Task/Y-combinator/GAP/y-combinator.gap
Normal file
35
Task/Y-combinator/GAP/y-combinator.gap
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
Y := function(f)
|
||||
local u;
|
||||
u := x -> x(x);
|
||||
return u(y -> f(a -> y(y)(a)));
|
||||
end;
|
||||
|
||||
fib := function(f)
|
||||
local u;
|
||||
u := function(n)
|
||||
if n < 2 then
|
||||
return n;
|
||||
else
|
||||
return f(n-1) + f(n-2);
|
||||
fi;
|
||||
end;
|
||||
return u;
|
||||
end;
|
||||
|
||||
Y(fib)(10);
|
||||
# 55
|
||||
|
||||
fac := function(f)
|
||||
local u;
|
||||
u := function(n)
|
||||
if n < 2 then
|
||||
return 1;
|
||||
else
|
||||
return n*f(n-1);
|
||||
fi;
|
||||
end;
|
||||
return u;
|
||||
end;
|
||||
|
||||
Y(fac)(8);
|
||||
# 40320
|
||||
19
Task/Y-combinator/Genyris/y-combinator.genyris
Normal file
19
Task/Y-combinator/Genyris/y-combinator.genyris
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
def fac (f)
|
||||
function (n)
|
||||
if (equal? n 0) 1
|
||||
* n (f (- n 1))
|
||||
def fib (f)
|
||||
function (n)
|
||||
cond
|
||||
(equal? n 0) 0
|
||||
(equal? n 1) 1
|
||||
else (+ (f (- n 1)) (f (- n 2)))
|
||||
|
||||
def Y (f)
|
||||
(function (x) (x x))
|
||||
function (y)
|
||||
f
|
||||
function (&rest args) (apply (y y) args)
|
||||
|
||||
assertEqual ((Y fac) 5) 120
|
||||
assertEqual ((Y fib) 8) 21
|
||||
41
Task/Y-combinator/Go/y-combinator.go
Normal file
41
Task/Y-combinator/Go/y-combinator.go
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Func func(int) int
|
||||
type FuncFunc func(Func) Func
|
||||
type RecursiveFunc func (RecursiveFunc) Func
|
||||
|
||||
func main() {
|
||||
fac := fix(almost_fac)
|
||||
fib := fix(almost_fib)
|
||||
fmt.Println("fac(10) = ", fac(10))
|
||||
fmt.Println("fib(10) = ", fib(10))
|
||||
}
|
||||
|
||||
func fix(f FuncFunc) Func {
|
||||
g := func(r RecursiveFunc) Func {
|
||||
return f(func(x int) int {
|
||||
return r(r)(x)
|
||||
})
|
||||
}
|
||||
return g(g)
|
||||
}
|
||||
|
||||
func almost_fac(f Func) Func {
|
||||
return func(x int) int {
|
||||
if x <= 1 {
|
||||
return 1
|
||||
}
|
||||
return x * f(x-1)
|
||||
}
|
||||
}
|
||||
|
||||
func almost_fib(f Func) Func {
|
||||
return func(x int) int {
|
||||
if x <= 2 {
|
||||
return 1
|
||||
}
|
||||
return f(x-1)+f(x-2)
|
||||
}
|
||||
}
|
||||
13
Task/Y-combinator/Groovy/y-combinator-1.groovy
Normal file
13
Task/Y-combinator/Groovy/y-combinator-1.groovy
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
def Y = { le -> ({ f -> f(f) })({ f -> le { x -> f(f)(x) } }) }
|
||||
|
||||
def factorial = Y { fac ->
|
||||
{ n -> n <= 2 ? n : n * fac(n - 1) }
|
||||
}
|
||||
|
||||
assert 2432902008176640000 == factorial(20G)
|
||||
|
||||
def fib = Y { fibStar ->
|
||||
{ n -> n <= 1 ? n : fibStar(n - 1) + fibStar(n - 2) }
|
||||
}
|
||||
|
||||
assert fib(10) == 55
|
||||
7
Task/Y-combinator/Groovy/y-combinator-2.groovy
Normal file
7
Task/Y-combinator/Groovy/y-combinator-2.groovy
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
def Y = { le -> ({ f -> f(f) })({ f -> le { Object[] args -> f(f)(*args) } }) }
|
||||
|
||||
def mul = Y { mulStar -> { a, b -> a ? b + mulStar(a - 1, b) : 0 } }
|
||||
|
||||
1.upto(10) {
|
||||
assert mul(it, 10) == it * 10
|
||||
}
|
||||
15
Task/Y-combinator/Haskell/y-combinator-1.hs
Normal file
15
Task/Y-combinator/Haskell/y-combinator-1.hs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
newtype Mu a = Roll { unroll :: Mu a -> a }
|
||||
|
||||
fix :: (a -> a) -> a
|
||||
fix = \f -> (\x -> f (unroll x x)) $ Roll (\x -> f (unroll x x))
|
||||
|
||||
fac :: Integer -> Integer
|
||||
fac = fix $ \f n -> if (n <= 0) then 1 else n * f (n-1)
|
||||
|
||||
fibs :: [Integer]
|
||||
fibs = fix $ \fbs -> 0 : 1 : fix zipP fbs (tail fbs)
|
||||
where zipP f (x:xs) (y:ys) = x+y : f xs ys
|
||||
|
||||
main = do
|
||||
print $ map fac [1 .. 20]
|
||||
print $ take 20 fibs
|
||||
28
Task/Y-combinator/Haskell/y-combinator-2.hs
Normal file
28
Task/Y-combinator/Haskell/y-combinator-2.hs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
fix :: (a -> a) -> a
|
||||
fix f = f (fix f)
|
||||
|
||||
fac :: Integer -> Integer
|
||||
fac' f n | n <= 0 = 1
|
||||
| otherwise = n * f (n-1)
|
||||
fac = fix fac'
|
||||
|
||||
-- a simple but wasteful exponential time definition:
|
||||
fib :: Integer -> Integer
|
||||
fib' f 0 = 0
|
||||
fib' f 1 = 1
|
||||
fib' f n = f (n-1) + f (n-2)
|
||||
fib = fix fib'
|
||||
|
||||
-- Or for far more efficiency, compute a lazy infinite list. This is
|
||||
-- a Y-combinator version of: fibs = 0:1:zipWith (+) fibs (tail fibs)
|
||||
fibs :: [Integer]
|
||||
fibs' a = 0:1:(fix zipP a (tail a))
|
||||
where
|
||||
zipP f (x:xs) (y:ys) = x+y : f xs ys
|
||||
fibs = fix fibs'
|
||||
|
||||
-- This code shows how the functions can be used:
|
||||
main = do
|
||||
print $ map fac [1 .. 20]
|
||||
print $ map fib [0 .. 19]
|
||||
print $ take 20 fibs
|
||||
1
Task/Y-combinator/J/y-combinator-1.j
Normal file
1
Task/Y-combinator/J/y-combinator-1.j
Normal file
|
|
@ -0,0 +1 @@
|
|||
Y=. ((((&>)/)(1 : '(5!:5)<''x'''))(&([ 128!:2 ,&<)))f.
|
||||
11
Task/Y-combinator/J/y-combinator-2.j
Normal file
11
Task/Y-combinator/J/y-combinator-2.j
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
u=. [ NB. Function (left)
|
||||
n=. ] NB. Argument (right)
|
||||
sr=. [ 128!:2 ,&< NB. Self referring
|
||||
|
||||
fac=. (1:`(n * u sr n - 1:)) @. (0: < n)
|
||||
fac f. Y 10
|
||||
3628800
|
||||
|
||||
Fib=. ((u sr n - 2:) + u sr n - 1:) ^: (1: < n)
|
||||
Fib f. Y 10
|
||||
55
|
||||
9
Task/Y-combinator/J/y-combinator-3.j
Normal file
9
Task/Y-combinator/J/y-combinator-3.j
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
fac f. Y NB. Showing the stateless recursive factorial function...
|
||||
'1:`(] * [ ([ 128!:2 ,&<) ] - 1:)@.(0: < ])&>/'&([ 128!:2 ,&<)
|
||||
fac f. NB. Showing the stateless factorial step...
|
||||
1:`(] * [ ([ 128!:2 ,&<) ] - 1:)@.(0: < ])
|
||||
|
||||
Fib f. Y NB. Showing the stateless recursive Fibonacci function...
|
||||
'(([ ([ 128!:2 ,&<) ] - 2:) + [ ([ 128!:2 ,&<) ] - 1:)^:(1: < ])&>/'&([ 128!:2 ,&<)
|
||||
Fib f. NB. Showing the stateless Fibonacci step...
|
||||
(([ ([ 128!:2 ,&<) ] - 2:) + [ ([ 128!:2 ,&<) ] - 1:)^:(1: < ])
|
||||
4
Task/Y-combinator/J/y-combinator-4.j
Normal file
4
Task/Y-combinator/J/y-combinator-4.j
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
sr=. [ 128!:2 ,&< NB. Self referring
|
||||
lw=. '(5!:5)<''x''' (1 :) NB. Linear representation of a word
|
||||
Y=. (&>)/lw(&sr) f.
|
||||
Y=. 'Y'f. NB. Fixing it
|
||||
40
Task/Y-combinator/J/y-combinator-5.j
Normal file
40
Task/Y-combinator/J/y-combinator-5.j
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
lambda=:3 :0
|
||||
if. 1=#;:y do.
|
||||
3 :(y,'=.y',LF,0 :0)`''
|
||||
else.
|
||||
(,<#;:y) Defer (3 :('''',y,'''=.y',LF,0 :0))`''
|
||||
end.
|
||||
)
|
||||
|
||||
Defer=:2 :0
|
||||
if. (_1 {:: m) <: #m do.
|
||||
v |. y;_1 }. m
|
||||
else.
|
||||
(y;m) Defer v`''
|
||||
end.
|
||||
)
|
||||
|
||||
recursivelY=: lambda 'g recur x'
|
||||
(g`:6 recur`:6 recur)`:6 x
|
||||
)
|
||||
|
||||
sivelY=: lambda 'g recur'
|
||||
(recursivelY`:6 g)`:6 recur
|
||||
)
|
||||
|
||||
Y=: lambda 'g'
|
||||
recur=. sivelY`:6 g
|
||||
recur`:6 recur
|
||||
)
|
||||
|
||||
almost_factorial=: lambda 'f n'
|
||||
if. 0 >: n do. 1
|
||||
else. n * f`:6 n-1 end.
|
||||
)
|
||||
|
||||
almost_fibonacci=: lambda 'f n'
|
||||
if. 2 > n do. n
|
||||
else. (f`:6 n-1) + f`:6 n-2 end.
|
||||
)
|
||||
|
||||
Ev=: `:6
|
||||
6
Task/Y-combinator/J/y-combinator-6.j
Normal file
6
Task/Y-combinator/J/y-combinator-6.j
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
(Y Ev almost_factorial)Ev 9
|
||||
362880
|
||||
(Y Ev almost_fibonacci)Ev 9
|
||||
34
|
||||
(Y Ev almost_fibonacci)Ev"0 i. 10
|
||||
0 1 1 2 3 5 8 13 21 34
|
||||
53
Task/Y-combinator/Java/y-combinator-1.java
Normal file
53
Task/Y-combinator/Java/y-combinator-1.java
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
interface Function<A, B> {
|
||||
public B call(A x);
|
||||
}
|
||||
|
||||
public class YCombinator {
|
||||
interface RecursiveFunc<F> extends Function<RecursiveFunc<F>, F> { }
|
||||
|
||||
public static <A,B> Function<A,B> fix(final Function<Function<A,B>, Function<A,B>> f) {
|
||||
RecursiveFunc<Function<A,B>> r =
|
||||
new RecursiveFunc<Function<A,B>>() {
|
||||
public Function<A,B> call(final RecursiveFunc<Function<A,B>> w) {
|
||||
return f.call(new Function<A,B>() {
|
||||
public B call(A x) {
|
||||
return w.call(w).call(x);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
return r.call(r);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Function<Function<Integer,Integer>, Function<Integer,Integer>> almost_fib =
|
||||
new Function<Function<Integer,Integer>, Function<Integer,Integer>>() {
|
||||
public Function<Integer,Integer> call(final Function<Integer,Integer> f) {
|
||||
return new Function<Integer,Integer>() {
|
||||
public Integer call(Integer n) {
|
||||
if (n <= 2) return 1;
|
||||
return f.call(n - 1) + f.call(n - 2);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
Function<Function<Integer,Integer>, Function<Integer,Integer>> almost_fac =
|
||||
new Function<Function<Integer,Integer>, Function<Integer,Integer>>() {
|
||||
public Function<Integer,Integer> call(final Function<Integer,Integer> f) {
|
||||
return new Function<Integer,Integer>() {
|
||||
public Integer call(Integer n) {
|
||||
if (n <= 1) return 1;
|
||||
return n * f.call(n - 1);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
Function<Integer,Integer> fib = fix(almost_fib);
|
||||
Function<Integer,Integer> fac = fix(almost_fac);
|
||||
|
||||
System.out.println("fib(10) = " + fib.call(10));
|
||||
System.out.println("fac(10) = " + fac.call(10));
|
||||
}
|
||||
}
|
||||
23
Task/Y-combinator/Java/y-combinator-2.java
Normal file
23
Task/Y-combinator/Java/y-combinator-2.java
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import java.util.function.Function;
|
||||
|
||||
public class YCombinator {
|
||||
interface RecursiveFunc<F> extends Function<RecursiveFunc<F>, F> { }
|
||||
public static <A,B> Function<A,B> fix(Function<Function<A,B>, Function<A,B>> f) {
|
||||
RecursiveFunc<Function<A,B>> r = w -> f.apply(x -> w.apply(w).apply(x));
|
||||
return r.apply(r);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Function<Integer,Integer> fib = fix(f -> n -> {
|
||||
if (n <= 2) return 1;
|
||||
return f.apply(n - 1) + f.apply(n - 2);
|
||||
});
|
||||
Function<Integer,Integer> fac = fix(f -> n -> {
|
||||
if (n <= 1) return 1;
|
||||
return n * f.apply(n - 1);
|
||||
});
|
||||
|
||||
System.out.println("fib(10) = " + fib.apply(10));
|
||||
System.out.println("fac(10) = " + fac.apply(10));
|
||||
}
|
||||
}
|
||||
142
Task/Y-combinator/Java/y-combinator-3.java
Normal file
142
Task/Y-combinator/Java/y-combinator-3.java
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
interface Function<INPUT, OUTPUT> {
|
||||
public static final List<Void> NIL = Collections.emptyList();
|
||||
public OUTPUT call(List<? extends INPUT> input);
|
||||
}
|
||||
|
||||
class Functions {
|
||||
public static <OUTPUT> OUTPUT call(
|
||||
Function<Void, OUTPUT> f) {
|
||||
return f.call(Function.NIL);
|
||||
}
|
||||
|
||||
public static <INPUT, OUTPUT> OUTPUT call(
|
||||
Function<INPUT, OUTPUT> f,
|
||||
INPUT input) {
|
||||
return f.call(Collections.singletonList(input));
|
||||
}
|
||||
|
||||
public static <INPUT, OUTPUT> OUTPUT call(
|
||||
Function<INPUT, OUTPUT> f,
|
||||
INPUT... input) {
|
||||
return f.call(Arrays.asList(input));
|
||||
}
|
||||
|
||||
public static <INPUT, OUTPUT> OUTPUT call(
|
||||
Function<INPUT, OUTPUT> f,
|
||||
Class<INPUT> type,
|
||||
INPUT... input) {
|
||||
List<INPUT> i = Collections.checkedList(new ArrayList<INPUT>(), type);
|
||||
i.addAll(Arrays.asList(input));
|
||||
return f.call(i);
|
||||
}
|
||||
|
||||
public static <T> T input(
|
||||
List<T> input, int index) {
|
||||
return input.size() > index
|
||||
? input.get(index)
|
||||
: null;
|
||||
}
|
||||
|
||||
public static <INPUT, INPUT_OUTPUT, OUTPUT> Function<INPUT, OUTPUT> compose(
|
||||
final Function<INPUT_OUTPUT, OUTPUT> f
|
||||
, final Function<INPUT, INPUT_OUTPUT> g) {
|
||||
return new Function<INPUT, OUTPUT>() {
|
||||
@Override
|
||||
public OUTPUT call(List<? extends INPUT> input) {
|
||||
return f.call(Collections.singletonList(g.call(input)));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <INPUT, OUTPUT> Function<INPUT, OUTPUT> y(
|
||||
final Function<Function<INPUT, OUTPUT>, Function<INPUT, OUTPUT>> f) {
|
||||
return new Function<INPUT, OUTPUT>() {
|
||||
@Override
|
||||
public OUTPUT call(List<? extends INPUT> input) {
|
||||
return Functions.call(f, new Function<INPUT, OUTPUT>() {
|
||||
@Override
|
||||
public OUTPUT call(List<? extends INPUT> input) {
|
||||
return y(f).call(input);
|
||||
}
|
||||
}).call(input);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class Y {
|
||||
public static BigInteger TWO = BigInteger.ONE.add(BigInteger.ONE);
|
||||
|
||||
public static void main(String[] args) {
|
||||
Function<Number, Number> fibonacci = Functions.y(
|
||||
new Function<Function<Number, Number>, Function<Number, Number>>() {
|
||||
@Override
|
||||
public Function<Number, Number> call(List<? extends Function<Number, Number>> input) {
|
||||
final Function<Number, Number> f = Functions.input(input, 0);
|
||||
return new Function<Number, Number>() {
|
||||
@Override
|
||||
public Number call(List<? extends Number> input) {
|
||||
BigInteger n = new BigInteger(Functions.input(input, 0).toString());
|
||||
if (n.compareTo(TWO) <= 0) return 1;
|
||||
return new BigInteger(Functions.call(f, n.subtract(BigInteger.ONE)).toString())
|
||||
.add(new BigInteger(Functions.call(f, n.subtract(TWO)).toString()));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
Function<Number, Number> factorial = Functions.y(
|
||||
new Function<Function<Number, Number>, Function<Number, Number>>() {
|
||||
@Override
|
||||
public Function<Number, Number> call(List<? extends Function<Number, Number>> input) {
|
||||
final Function<Number, Number> f = Functions.input(input, 0);
|
||||
return new Function<Number, Number>() {
|
||||
@Override
|
||||
public Number call(List<? extends Number> input) {
|
||||
BigInteger n = new BigInteger(Functions.input(input, 0).toString());
|
||||
if (n.compareTo(BigInteger.ONE) <= 0) return 1;
|
||||
return n.multiply(
|
||||
new BigInteger(Functions.call(f, n.subtract(BigInteger.ONE)).toString())
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
Function<Number, Number> ackermann = Functions.y(
|
||||
new Function<Function<Number, Number>, Function<Number, Number>>() {
|
||||
@Override
|
||||
public Function<Number, Number> call(List<? extends Function<Number, Number>> input) {
|
||||
final Function<Number, Number> f = Functions.input(input, 0);
|
||||
return new Function<Number, Number>() {
|
||||
@Override
|
||||
public Number call(List<? extends Number> input) {
|
||||
BigInteger m = new BigInteger(Functions.input(input, 0) + "");
|
||||
BigInteger n = new BigInteger(Functions.input(input, 1) + "");
|
||||
return m.equals(BigInteger.ZERO)
|
||||
? n.add(BigInteger.ONE)
|
||||
: Functions.call(f, m.subtract(BigInteger.ONE),
|
||||
n.equals(BigInteger.ZERO)
|
||||
? BigInteger.ONE
|
||||
: Functions.call(f, m, n.subtract(BigInteger.ONE)));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
System.out.println("fibonacci(10) = " + Functions.call(fibonacci, 10));
|
||||
System.out.println("factorial(10) = " + Functions.call(factorial, 10));
|
||||
System.out.println("ackermann(3, 7) = " + Functions.call(ackermann, 3, 7));
|
||||
}
|
||||
}
|
||||
147
Task/Y-combinator/Java/y-combinator-4.java
Normal file
147
Task/Y-combinator/Java/y-combinator-4.java
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@FunctionalInterface
|
||||
interface VarargFunction<INPUT, OUTPUT> {
|
||||
public OUTPUT apply(List<? extends INPUT> input);
|
||||
|
||||
public default OUTPUT apply() {
|
||||
return apply(Collections.emptyList());
|
||||
}
|
||||
|
||||
public default OUTPUT apply(INPUT input) {
|
||||
return apply(Collections.singletonList(input));
|
||||
}
|
||||
|
||||
public default OUTPUT apply(INPUT input, INPUT input2) {
|
||||
return apply(Arrays.asList(input, input2));
|
||||
}
|
||||
|
||||
public default OUTPUT apply(INPUT input, INPUT input2, INPUT input3) {
|
||||
return apply(Arrays.asList(input, input2, input3));
|
||||
}
|
||||
|
||||
public default OUTPUT apply(Class<INPUT> type, Object... input) {
|
||||
List<INPUT> i = Collections.checkedList(new ArrayList<>(), type);
|
||||
for (Object object : input) {
|
||||
i.add(type.cast(object));
|
||||
}
|
||||
return apply(i);
|
||||
}
|
||||
|
||||
public default <POST_OUTPUT> VarargFunction<INPUT, POST_OUTPUT> compose(
|
||||
VarargFunction<OUTPUT, POST_OUTPUT> after) {
|
||||
return input -> after.apply(apply(input));
|
||||
}
|
||||
|
||||
public default Function<INPUT, OUTPUT> toFunction() {
|
||||
return input -> apply(input);
|
||||
}
|
||||
|
||||
public default BiFunction<INPUT, INPUT, OUTPUT> toBiFunction() {
|
||||
return (input, input2) -> apply(input, input2);
|
||||
}
|
||||
|
||||
public default <PRE_INPUT> VarargFunction<PRE_INPUT, OUTPUT> transformArguments(Function<PRE_INPUT, INPUT> transformer) {
|
||||
return input -> apply(input.parallelStream().map(transformer).collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface SelfApplicable<OUTPUT> {
|
||||
OUTPUT apply(SelfApplicable<OUTPUT> input);
|
||||
}
|
||||
|
||||
class Utils {
|
||||
public static <T> T input( List<T> input, int index) {
|
||||
return input.size() > index ? input.get(index) : null;
|
||||
}
|
||||
|
||||
/* Based on https://gist.github.com/aruld/3965968/#comment-604392 */
|
||||
|
||||
public static <INPUT, OUTPUT> SelfApplicable<Function<Function<Function<INPUT, OUTPUT>, Function<INPUT, OUTPUT>>, Function<INPUT, OUTPUT>>> y(Class<INPUT> input, Class<OUTPUT> output) {
|
||||
return y -> f -> x -> f.apply(y.apply(y).apply(f)).apply(x);
|
||||
}
|
||||
|
||||
public static <INPUT, OUTPUT> Function<Function<Function<INPUT, OUTPUT>, Function<INPUT, OUTPUT>>, Function<INPUT, OUTPUT>> fix(Class<INPUT> input, Class<OUTPUT> output) {
|
||||
return y(input, output).apply(y(input, output));
|
||||
}
|
||||
|
||||
public static <INPUT, OUTPUT> SelfApplicable<Function<Function<VarargFunction<INPUT, OUTPUT>, VarargFunction<INPUT, OUTPUT>>, VarargFunction<INPUT, OUTPUT>>> yVararg(Class<INPUT> input, Class<OUTPUT> output) {
|
||||
return y -> f -> x -> f.apply(y.apply(y).apply(f)).apply(x);
|
||||
}
|
||||
|
||||
public static <INPUT, OUTPUT> Function<Function<VarargFunction<INPUT, OUTPUT>, VarargFunction<INPUT, OUTPUT>>, VarargFunction<INPUT, OUTPUT>> fixVararg(Class<INPUT> input, Class<OUTPUT> output) {
|
||||
return yVararg(input, output).apply(yVararg(input, output));
|
||||
}
|
||||
|
||||
public static <INPUT, OUTPUT> VarargFunction<INPUT, OUTPUT> toVarargFunction(Function<INPUT, OUTPUT> function) {
|
||||
return input -> function.apply(Utils.input(input, 0));
|
||||
}
|
||||
|
||||
public static <INPUT, OUTPUT> VarargFunction<INPUT, OUTPUT> toVarargFunction(BiFunction<INPUT, INPUT, OUTPUT> function) {
|
||||
return input -> function.apply(Utils.input(input, 0), Utils.input(input, 1));
|
||||
}
|
||||
}
|
||||
|
||||
public class Y {
|
||||
public static final BigInteger TWO = BigInteger.ONE.add(BigInteger.ONE);
|
||||
|
||||
public static final Function<Number, BigInteger> toBigInteger = ((Function<Number, Long>) Number::longValue).compose(BigInteger::valueOf);
|
||||
|
||||
public static void main(String[] args) {
|
||||
VarargFunction<Number, Number> fibonacci = Utils.fixVararg(Number.class, Number.class).apply(
|
||||
f -> Utils.toVarargFunction(
|
||||
toBigInteger.compose(
|
||||
n -> (n.compareTo(TWO) <= 0) ? 1
|
||||
: new BigInteger(f.apply(n.subtract(BigInteger.ONE)).toString())
|
||||
.add(new BigInteger(f.apply(n.subtract(TWO)).toString()))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
VarargFunction<Number, Number> factorial = Utils.fixVararg(Number.class, Number.class).apply(
|
||||
f -> Utils.toVarargFunction(
|
||||
toBigInteger.compose(
|
||||
n -> (n.compareTo(BigInteger.ONE) <= 0) ? 1
|
||||
: n.multiply(new BigInteger(f.apply(n.subtract(BigInteger.ONE)).toString()))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
VarargFunction<Number, Number> ackermann = Utils.fixVararg(Number.class, Number.class).apply(
|
||||
f -> Utils.toVarargFunction(
|
||||
(BigInteger m, BigInteger n) -> m.equals(BigInteger.ZERO) ? n.add(BigInteger.ONE)
|
||||
: f.apply(m.subtract(BigInteger.ONE),
|
||||
n.equals(BigInteger.ZERO)
|
||||
? BigInteger.ONE
|
||||
: f.apply(m, n.subtract(BigInteger.ONE)))
|
||||
).transformArguments(toBigInteger)
|
||||
);
|
||||
|
||||
Map<String, VarargFunction<Number, Number>> functions = new HashMap<>();
|
||||
functions.put("fibonacci", fibonacci);
|
||||
functions.put("factorial", factorial);
|
||||
functions.put("ackermann", ackermann);
|
||||
|
||||
Map<VarargFunction<Number, Number>, List<Number>> arguments = new HashMap<>();
|
||||
arguments.put(functions.get("fibonacci"), Arrays.asList(20));
|
||||
arguments.put(functions.get("factorial"), Arrays.asList(10));
|
||||
arguments.put(functions.get("ackermann"), Arrays.asList(3, 2));
|
||||
|
||||
functions.entrySet().parallelStream().map(
|
||||
entry ->
|
||||
entry.getKey() + arguments.get(entry.getValue()) + " = "
|
||||
+ entry.getValue().apply(arguments.get(entry.getValue()))
|
||||
).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
3
Task/Y-combinator/Java/y-combinator-5.java
Normal file
3
Task/Y-combinator/Java/y-combinator-5.java
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
factorial[10] = 3628800
|
||||
ackermann[3, 2] = 29
|
||||
fibonacci[20] = 6765
|
||||
18
Task/Y-combinator/JavaScript/y-combinator-1.js
Normal file
18
Task/Y-combinator/JavaScript/y-combinator-1.js
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
function Y(f) {
|
||||
var g = f(function() {
|
||||
return g.apply(this, arguments);
|
||||
});
|
||||
return g;
|
||||
}
|
||||
|
||||
var fac = Y(function(f) {
|
||||
return function(n) {
|
||||
return n > 1 ? n * f(n - 1) : 1;
|
||||
};
|
||||
});
|
||||
|
||||
var fib = Y(function(f) {
|
||||
return function(n) {
|
||||
return n > 1 ? f(n - 1) + f(n - 2) : n;
|
||||
};
|
||||
});
|
||||
14
Task/Y-combinator/JavaScript/y-combinator-2.js
Normal file
14
Task/Y-combinator/JavaScript/y-combinator-2.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
function Y(f) {
|
||||
var g = f((function(h) {
|
||||
return function() {
|
||||
var g = f(h(h));
|
||||
return g.apply(this, arguments);
|
||||
}
|
||||
})(function(h) {
|
||||
return function() {
|
||||
var g = f(h(h));
|
||||
return g.apply(this, arguments);
|
||||
}
|
||||
}));
|
||||
return g;
|
||||
}
|
||||
9
Task/Y-combinator/JavaScript/y-combinator-3.js
Normal file
9
Task/Y-combinator/JavaScript/y-combinator-3.js
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
function Y(f) {
|
||||
return (function(h) {
|
||||
return h(h);
|
||||
})(function(h) {
|
||||
return f(function() {
|
||||
return h(h).apply(this, arguments);
|
||||
});
|
||||
});
|
||||
}
|
||||
13
Task/Y-combinator/JavaScript/y-combinator-4.js
Normal file
13
Task/Y-combinator/JavaScript/y-combinator-4.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
function pseudoY(f) {
|
||||
return function g() {
|
||||
return f.apply(g, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
var fac = pseudoY(function(n) {
|
||||
return n > 1 ? n * this(n - 1) : 1;
|
||||
});
|
||||
|
||||
var fib = pseudoY(function(n) {
|
||||
return n > 1 ? this(n - 1) + this(n - 2) : n;
|
||||
});
|
||||
3
Task/Y-combinator/Joy/y-combinator.joy
Normal file
3
Task/Y-combinator/Joy/y-combinator.joy
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
DEFINE y == [dup cons] swap concat dup cons i;
|
||||
|
||||
fac == [ [pop null] [pop succ] [[dup pred] dip i *] ifte ] y.
|
||||
5
Task/Y-combinator/Lua/y-combinator-1.lua
Normal file
5
Task/Y-combinator/Lua/y-combinator-1.lua
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Y = function (f)
|
||||
return function(...)
|
||||
return (function(x) return x(x) end)(function(x) return f(function(y) return x(x)(y) end) end)(...)
|
||||
end
|
||||
end
|
||||
4
Task/Y-combinator/Lua/y-combinator-2.lua
Normal file
4
Task/Y-combinator/Lua/y-combinator-2.lua
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
almostfactorial = function(f) return function(n) return n > 0 and n * f(n-1) or 1 end end
|
||||
almostfibs = function(f) return function(n) return n < 2 and n or f(n-1) + f(n-2) end end
|
||||
factorial, fibs = Y(almostfactorial), Y(almostfibs)
|
||||
print(factorial(7))
|
||||
7
Task/Y-combinator/Maple/y-combinator.maple
Normal file
7
Task/Y-combinator/Maple/y-combinator.maple
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
> Y:=f->(x->x(x))(g->f((()->g(g)(args)))):
|
||||
> Yfac:=Y(f->(x->`if`(x<2,1,x*f(x-1)))):
|
||||
> seq( Yfac( i ), i = 1 .. 10 );
|
||||
1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800
|
||||
> Yfib:=Y(f->(x->`if`(x<2,x,f(x-1)+f(x-2)))):
|
||||
> seq( Yfib( i ), i = 1 .. 10 );
|
||||
1, 1, 2, 3, 5, 8, 13, 21, 34, 55
|
||||
3
Task/Y-combinator/Mathematica/y-combinator.math
Normal file
3
Task/Y-combinator/Mathematica/y-combinator.math
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
Y = Function[f, #@# &@Function[x, f[x[x]@# &]]];
|
||||
factorial = Y@Function[f, If[# < 1, 1, # f[# - 1]] &];
|
||||
fibonacci = Y@Function[f, If[# < 2, #, f[# - 1] + f[# - 2]] &];
|
||||
1
Task/Y-combinator/OCaml/y-combinator-1.ocaml
Normal file
1
Task/Y-combinator/OCaml/y-combinator-1.ocaml
Normal file
|
|
@ -0,0 +1 @@
|
|||
let fix f g = (fun x a -> f (x x) a) (fun x a -> f (x x) a) g
|
||||
1
Task/Y-combinator/OCaml/y-combinator-2.ocaml
Normal file
1
Task/Y-combinator/OCaml/y-combinator-2.ocaml
Normal file
|
|
@ -0,0 +1 @@
|
|||
let fix f = (fun (`X x) -> f(x (`X x))) (`X(fun (`X x) y -> f(x (`X x)) y));;
|
||||
27
Task/Y-combinator/OCaml/y-combinator-3.ocaml
Normal file
27
Task/Y-combinator/OCaml/y-combinator-3.ocaml
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
type 'a mu = Roll of ('a mu -> 'a);;
|
||||
|
||||
let unroll (Roll x) = x;;
|
||||
|
||||
let fix f = (fun x a -> f (unroll x x) a) (Roll (fun x a -> f (unroll x x) a));;
|
||||
|
||||
let fac f = function
|
||||
0 -> 1
|
||||
| n -> n * f (n-1)
|
||||
;;
|
||||
|
||||
let fib f = function
|
||||
0 -> 0
|
||||
| 1 -> 1
|
||||
| n -> f (n-1) + f (n-2)
|
||||
;;
|
||||
|
||||
(* val unroll : 'a mu -> 'a mu -> 'a = <fun>
|
||||
val fix : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b = <fun>
|
||||
val fac : (int -> int) -> int -> int = <fun>
|
||||
val fib : (int -> int) -> int -> int = <fun> *)
|
||||
|
||||
fix fac 5;;
|
||||
(* - : int = 120 *)
|
||||
|
||||
fix fib 8;;
|
||||
(* - : int = 21 *)
|
||||
1
Task/Y-combinator/OCaml/y-combinator-4.ocaml
Normal file
1
Task/Y-combinator/OCaml/y-combinator-4.ocaml
Normal file
|
|
@ -0,0 +1 @@
|
|||
let rec fix f x = f (fix f) x;;
|
||||
42
Task/Y-combinator/Objective-C/y-combinator.m
Normal file
42
Task/Y-combinator/Objective-C/y-combinator.m
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
typedef int (^Func)(int);
|
||||
typedef Func (^FuncFunc)(Func);
|
||||
typedef Func (^RecursiveFunc)(id); // hide recursive typing behind dynamic typing
|
||||
|
||||
Func fix (FuncFunc f) {
|
||||
RecursiveFunc r =
|
||||
^(id y) {
|
||||
RecursiveFunc w = y; // cast value back into desired type
|
||||
return f(^(int x) {
|
||||
return w(w)(x);
|
||||
});
|
||||
};
|
||||
return r(r);
|
||||
}
|
||||
|
||||
int main (int argc, const char *argv[]) {
|
||||
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
FuncFunc almost_fac = ^Func(Func f) {
|
||||
return [[^(int n) {
|
||||
if (n <= 1) return 1;
|
||||
return n * f(n - 1);
|
||||
} copy] autorelease];
|
||||
};
|
||||
|
||||
FuncFunc almost_fib = ^Func(Func f) {
|
||||
return [[^(int n) {
|
||||
if (n <= 2) return 1;
|
||||
return f(n - 1) + f(n - 2);
|
||||
} copy] autorelease];
|
||||
};
|
||||
|
||||
Func fib = fix(almost_fib);
|
||||
Func fac = fix(almost_fac);
|
||||
NSLog(@"fib(10) = %d", fib(10));
|
||||
NSLog(@"fac(10) = %d", fac(10));
|
||||
|
||||
[pool release];
|
||||
return 0;
|
||||
}
|
||||
19
Task/Y-combinator/Order/y-combinator.order
Normal file
19
Task/Y-combinator/Order/y-combinator.order
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#include <order/interpreter.h>
|
||||
|
||||
#define ORDER_PP_DEF_8y \
|
||||
ORDER_PP_FN(8fn(8F, \
|
||||
8let((8R, 8fn(8G, \
|
||||
8ap(8F, 8fn(8A, 8ap(8ap(8G, 8G), 8A))))), \
|
||||
8ap(8R, 8R))))
|
||||
|
||||
#define ORDER_PP_DEF_8fac \
|
||||
ORDER_PP_FN(8fn(8F, 8X, \
|
||||
8if(8less_eq(8X, 0), 1, 8times(8X, 8ap(8F, 8minus(8X, 1))))))
|
||||
|
||||
#define ORDER_PP_DEF_8fib \
|
||||
ORDER_PP_FN(8fn(8F, 8X, \
|
||||
8if(8less(8X, 2), 8X, 8plus(8ap(8F, 8minus(8X, 1)), \
|
||||
8ap(8F, 8minus(8X, 2))))))
|
||||
|
||||
ORDER_PP(8to_lit(8ap(8y(8fac), 10))) // 3628800
|
||||
ORDER_PP(8ap(8y(8fib), 10)) // 55
|
||||
23
Task/Y-combinator/Oz/y-combinator.oz
Normal file
23
Task/Y-combinator/Oz/y-combinator.oz
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
declare
|
||||
Y = fun {$ F}
|
||||
{fun {$ X} {X X} end
|
||||
fun {$ X} {F fun {$ Z} {{X X} Z} end} end}
|
||||
end
|
||||
|
||||
Fac = {Y fun {$ F}
|
||||
fun {$ N}
|
||||
if N == 0 then 1 else N*{F N-1} end
|
||||
end
|
||||
end}
|
||||
|
||||
Fib = {Y fun {$ F}
|
||||
fun {$ N}
|
||||
case N of 0 then 0
|
||||
[] 1 then 1
|
||||
else {F N-1} + {F N-2}
|
||||
end
|
||||
end
|
||||
end}
|
||||
in
|
||||
{Show {Fac 5}}
|
||||
{Show {Fib 8}}
|
||||
22
Task/Y-combinator/PHP/y-combinator-1.php
Normal file
22
Task/Y-combinator/PHP/y-combinator-1.php
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
function Y($f) {
|
||||
$g = function($w) use($f) {
|
||||
return $f(function() use($w) {
|
||||
return call_user_func_array($w($w), func_get_args());
|
||||
});
|
||||
};
|
||||
return $g($g);
|
||||
}
|
||||
|
||||
$fibonacci = Y(function($f) {
|
||||
return function($i) use($f) { return ($i <= 1) ? $i : ($f($i-1) + $f($i-2)); };
|
||||
});
|
||||
|
||||
echo $fibonacci(10), "\n";
|
||||
|
||||
$factorial = Y(function($f) {
|
||||
return function($i) use($f) { return ($i <= 1) ? 1 : ($f($i - 1) * $i); };
|
||||
});
|
||||
|
||||
echo $factorial(10), "\n";
|
||||
?>
|
||||
26
Task/Y-combinator/PHP/y-combinator-2.php
Normal file
26
Task/Y-combinator/PHP/y-combinator-2.php
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
function Y($f) {
|
||||
$g = create_function('$w', '$f = '.var_export($f,true).';
|
||||
return $f(create_function(\'\', \'$w = \'.var_export($w,true).\';
|
||||
return call_user_func_array($w($w), func_get_args());
|
||||
\'));
|
||||
');
|
||||
return $g($g);
|
||||
}
|
||||
|
||||
function almost_fib($f) {
|
||||
return create_function('$i', '$f = '.var_export($f,true).';
|
||||
return ($i <= 1) ? $i : ($f($i-1) + $f($i-2));
|
||||
');
|
||||
};
|
||||
$fibonacci = Y('almost_fib');
|
||||
echo $fibonacci(10), "\n";
|
||||
|
||||
function almost_fac($f) {
|
||||
return create_function('$i', '$f = '.var_export($f,true).';
|
||||
return ($i <= 1) ? 1 : ($f($i - 1) * $i);
|
||||
');
|
||||
};
|
||||
$factorial = Y('almost_fac');
|
||||
echo $factorial(10), "\n";
|
||||
?>
|
||||
5
Task/Y-combinator/Perl-6/y-combinator-1.pl6
Normal file
5
Task/Y-combinator/Perl-6/y-combinator-1.pl6
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
sub Y ($f) { { .($_) }( -> $y { $f({ $y($y)($^arg) }) } ) }
|
||||
sub fac ($f) { sub ($n) { $n < 2 ?? 1 !! $n * $f($n - 1) } }
|
||||
say map(Y(&fac), ^10).perl;
|
||||
sub fib ($f) { sub ($n) { $n < 2 ?? $n !! $f($n - 1) + $f($n - 2) } }
|
||||
say map(Y(&fib), ^10).perl;
|
||||
1
Task/Y-combinator/Perl-6/y-combinator-2.pl6
Normal file
1
Task/Y-combinator/Perl-6/y-combinator-2.pl6
Normal file
|
|
@ -0,0 +1 @@
|
|||
say .(10) given sub (Int $x) { $x < 2 ?? 1 !! $x * &?ROUTINE($x - 1); }
|
||||
5
Task/Y-combinator/Perl/y-combinator.pl
Normal file
5
Task/Y-combinator/Perl/y-combinator.pl
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
my $Y = sub { my ($f) = @_; sub {my ($x) = @_; $x->($x)}->(sub {my ($y) = @_; $f->(sub {$y->($y)->(@_)})})};
|
||||
my $fac = sub {my ($f) = @_; sub {my ($n) = @_; $n < 2 ? 1 : $n * $f->($n-1)}};
|
||||
print join(' ', map {$Y->($fac)->($_)} 0..9), "\n";
|
||||
my $fib = sub {my ($f) = @_; sub {my ($n) = @_; $n == 0 ? 0 : $n == 1 ? 1 : $f->($n-1) + $f->($n-2)}};
|
||||
print join(' ', map {$Y->($fib)->($_)} 0..9), "\n";
|
||||
3
Task/Y-combinator/PicoLisp/y-combinator-1.l
Normal file
3
Task/Y-combinator/PicoLisp/y-combinator-1.l
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
(de Y (F)
|
||||
(let X (curry (F) (Y) (F (curry (Y) @ (pass (Y Y)))))
|
||||
(X X) ) )
|
||||
9
Task/Y-combinator/PicoLisp/y-combinator-2.l
Normal file
9
Task/Y-combinator/PicoLisp/y-combinator-2.l
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Factorial
|
||||
(de fact (F)
|
||||
(curry (F) (N)
|
||||
(if (=0 N)
|
||||
1
|
||||
(* N (F (dec N))) ) ) )
|
||||
|
||||
: ((Y fact) 6)
|
||||
-> 720
|
||||
9
Task/Y-combinator/PicoLisp/y-combinator-3.l
Normal file
9
Task/Y-combinator/PicoLisp/y-combinator-3.l
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Fibonacci
|
||||
(de fibo (F)
|
||||
(curry (F) (N)
|
||||
(if (> 2 N)
|
||||
1
|
||||
(+ (F (dec N)) (F (- N 2))) ) ) )
|
||||
|
||||
: ((Y fibo) 22)
|
||||
-> 28657
|
||||
10
Task/Y-combinator/PicoLisp/y-combinator-4.l
Normal file
10
Task/Y-combinator/PicoLisp/y-combinator-4.l
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# Ackermann
|
||||
(de ack (F)
|
||||
(curry (F) (X Y)
|
||||
(cond
|
||||
((=0 X) (inc Y))
|
||||
((=0 Y) (F (dec X) 1))
|
||||
(T (F (dec X) (F X (dec Y)))) ) ) )
|
||||
|
||||
: ((Y ack) 3 4)
|
||||
-> 125
|
||||
22
Task/Y-combinator/Pop11/y-combinator.pop11
Normal file
22
Task/Y-combinator/Pop11/y-combinator.pop11
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
define Y(f);
|
||||
procedure (x); x(x) endprocedure(
|
||||
procedure (y);
|
||||
f(procedure(z); (y(y))(z) endprocedure)
|
||||
endprocedure
|
||||
)
|
||||
enddefine;
|
||||
|
||||
define fac(h);
|
||||
procedure (n);
|
||||
if n = 0 then 1 else n * h(n - 1) endif
|
||||
endprocedure
|
||||
enddefine;
|
||||
|
||||
define fib(h);
|
||||
procedure (n);
|
||||
if n < 2 then 1 else h(n - 1) + h(n - 2) endif
|
||||
endprocedure
|
||||
enddefine;
|
||||
|
||||
Y(fac)(5) =>
|
||||
Y(fib)(5) =>
|
||||
8
Task/Y-combinator/PostScript/y-combinator.ps
Normal file
8
Task/Y-combinator/PostScript/y-combinator.ps
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
y {
|
||||
{dup cons} exch concat dup cons i
|
||||
}.
|
||||
|
||||
/fac {
|
||||
{ {pop zero?} {pop succ} {{dup pred} dip i *} ifte }
|
||||
y
|
||||
}.
|
||||
51
Task/Y-combinator/PowerShell/y-combinator.psh
Normal file
51
Task/Y-combinator/PowerShell/y-combinator.psh
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
$fac = {
|
||||
param([ScriptBlock] $f)
|
||||
invoke-expression @"
|
||||
{
|
||||
param([int] `$n)
|
||||
if (`$n -le 0) {1}
|
||||
else {`$n * {$f}.InvokeReturnAsIs(`$n - 1)}
|
||||
}
|
||||
"@
|
||||
}
|
||||
|
||||
$fib = {
|
||||
param([ScriptBlock] $f)
|
||||
invoke-expression @"
|
||||
{
|
||||
param([int] `$n)
|
||||
switch (`$n)
|
||||
{
|
||||
0 {1}
|
||||
1 {1}
|
||||
default {{$f}.InvokeReturnAsIs(`$n-1)+{$f}.InvokeReturnAsIs(`$n-2)}
|
||||
}
|
||||
}
|
||||
"@
|
||||
}
|
||||
|
||||
$Z = {
|
||||
param([ScriptBlock] $f)
|
||||
invoke-expression @"
|
||||
{
|
||||
param([ScriptBlock] `$x)
|
||||
{$f}.InvokeReturnAsIs(`$(invoke-expression @`"
|
||||
{
|
||||
param(```$y)
|
||||
{`$x}.InvokeReturnAsIs({`$x}).InvokeReturnAsIs(```$y)
|
||||
}
|
||||
`"@))
|
||||
}.InvokeReturnAsIs({
|
||||
param([ScriptBlock] `$x)
|
||||
{$f}.InvokeReturnAsIs(`$(invoke-expression @`"
|
||||
{
|
||||
param(```$y)
|
||||
{`$x}.InvokeReturnAsIs({`$x}).InvokeReturnAsIs(```$y)
|
||||
}
|
||||
`"@))
|
||||
})
|
||||
"@
|
||||
}
|
||||
|
||||
$Z.InvokeReturnAsIs($fac).InvokeReturnAsIs(5)
|
||||
$Z.InvokeReturnAsIs($fib).InvokeReturnAsIs(5)
|
||||
32
Task/Y-combinator/Prolog/y-combinator.pro
Normal file
32
Task/Y-combinator/Prolog/y-combinator.pro
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
:- use_module(lambda).
|
||||
|
||||
% The Y combinator
|
||||
y(P, Arg, R) :-
|
||||
Pred = P +\Nb2^F2^call(P,Nb2,F2,P),
|
||||
call(Pred, Arg, R).
|
||||
|
||||
|
||||
test_y_combinator :-
|
||||
% code for Fibonacci function
|
||||
Fib = \NFib^RFib^RFibr1^(NFib < 2 ->
|
||||
RFib = NFib
|
||||
;
|
||||
NFib1 is NFib - 1,
|
||||
NFib2 is NFib - 2,
|
||||
call(RFibr1,NFib1,RFib1,RFibr1),
|
||||
call(RFibr1,NFib2,RFib2,RFibr1),
|
||||
RFib is RFib1 + RFib2
|
||||
),
|
||||
|
||||
y(Fib, 10, FR), format('Fib(~w) = ~w~n', [10, FR]),
|
||||
|
||||
% code for Factorial function
|
||||
Fact = \NFact^RFact^RFactr1^(NFact = 1 ->
|
||||
RFact = NFact
|
||||
;
|
||||
NFact1 is NFact - 1,
|
||||
call(RFactr1,NFact1,RFact1,RFactr1),
|
||||
RFact is NFact * RFact1
|
||||
),
|
||||
|
||||
y(Fact, 10, FF), format('Fact(~w) = ~w~n', [10, FF]).
|
||||
7
Task/Y-combinator/Python/y-combinator.py
Normal file
7
Task/Y-combinator/Python/y-combinator.py
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
>>> Y = lambda f: (lambda x: x(x))(lambda y: f(lambda *args: y(y)(*args)))
|
||||
>>> fac = lambda f: lambda n: (1 if n<2 else n*f(n-1))
|
||||
>>> [ Y(fac)(i) for i in range(10) ]
|
||||
[1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
|
||||
>>> fib = lambda f: lambda n: 0 if n == 0 else (1 if n == 1 else f(n-1) + f(n-2))
|
||||
>>> [ Y(fib)(i) for i in range(10) ]
|
||||
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
|
||||
3
Task/Y-combinator/R/y-combinator-1.r
Normal file
3
Task/Y-combinator/R/y-combinator-1.r
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
Y <- function(f) {
|
||||
(function(x) { (x)(x) })( function(y) { f( (function(a) {y(y)})(a) ) } )
|
||||
}
|
||||
17
Task/Y-combinator/R/y-combinator-2.r
Normal file
17
Task/Y-combinator/R/y-combinator-2.r
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
fac <- function(f) {
|
||||
function(n) {
|
||||
if (n<2)
|
||||
1
|
||||
else
|
||||
n*f(n-1)
|
||||
}
|
||||
}
|
||||
|
||||
fib <- function(f) {
|
||||
function(n) {
|
||||
if (n <= 1)
|
||||
n
|
||||
else
|
||||
f(n-1) + f(n-2)
|
||||
}
|
||||
}
|
||||
2
Task/Y-combinator/R/y-combinator-3.r
Normal file
2
Task/Y-combinator/R/y-combinator-3.r
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
for(i in 1:9) print(Y(fac)(i))
|
||||
for(i in 1:9) print(Y(fib)(i))
|
||||
1
Task/Y-combinator/REBOL/y-combinator-1.rebol
Normal file
1
Task/Y-combinator/REBOL/y-combinator-1.rebol
Normal file
|
|
@ -0,0 +1 @@
|
|||
Y: closure [g] [do func [f] [f :f] closure [f] [g func [x] [do f :f :x]]]
|
||||
2
Task/Y-combinator/REBOL/y-combinator-2.rebol
Normal file
2
Task/Y-combinator/REBOL/y-combinator-2.rebol
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
fact*: closure [h] [func [n] [either n <= 1 [1] [n * h n - 1]]]
|
||||
fact: Y :fact*
|
||||
24
Task/Y-combinator/REXX/y-combinator.rexx
Normal file
24
Task/Y-combinator/REXX/y-combinator.rexx
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*REXX program to implement a stateless Y combinator. */
|
||||
numeric digits 1000 /*allow big 'uns. */
|
||||
|
||||
say ' fib' Y(fib (50)) /*Fibonacci series*/
|
||||
say ' fib' Y(fib (12 11 10 9 8 7 6 5 4 3 2 1 0)) /*Fibonacci series*/
|
||||
say ' fact' Y(fact (60)) /*single fact. */
|
||||
say ' fact' Y(fact (0 1 2 3 4 5 6 7 8 9 10 11)) /*single fact. */
|
||||
say ' Dfact' Y(dfact (4 5 6 7 8 9 10 11 12 13)) /*double fact. */
|
||||
say ' Tfact' Y(tfact (4 5 6 7 8 9 10 11 12 13)) /*triple fact. */
|
||||
say ' Qfact' Y(qfact (4 5 6 7 8 40)) /*quadruple fact. */
|
||||
say ' length' Y(length (when for to where whenceforth)) /*lengths of words*/
|
||||
say 'reverse' Y(reverse (23 678 1007 45 MAS I MA)) /*reverses strings*/
|
||||
say ' trunc' Y(trunc (-7.0005 12 3.14159 6.4 78.999)) /*truncates numbs.*/
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
|
||||
/*──────────────────────────────────subroutines─────────────────────────*/
|
||||
Y: lambda=; parse arg Y _; do j=1 for words(_); interpret ,
|
||||
'lambda=lambda' Y'('word(_,j)')'; end; return lambda
|
||||
fib: procedure; parse arg x; if x<2 then return x; s=0; a=0; b=1
|
||||
do j=2 to x; s=a+b; a=b; b=s; end; return s
|
||||
dfact: procedure; arg x; !=1; do j=x to 2 by -2;!=!*j; end; return !
|
||||
tfact: procedure; arg x; !=1; do j=x to 2 by -3;!=!*j; end; return !
|
||||
qfact: procedure; arg x; !=1; do j=x to 2 by -4;!=!*j; end; return !
|
||||
fact: procedure; arg x; !=1; do j=2 to x ;!=!*j; end; return !
|
||||
14
Task/Y-combinator/Ruby/y-combinator-1.rb
Normal file
14
Task/Y-combinator/Ruby/y-combinator-1.rb
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
irb(main):001:0> Y = lambda do |f|
|
||||
irb(main):002:1* lambda {|g| g[g]}[lambda do |g|
|
||||
irb(main):003:3* f[lambda {|*args| g[g][*args]}]
|
||||
irb(main):004:3> end]
|
||||
irb(main):005:1> end
|
||||
=> #<Proc:0x00000204f5e6e0@(irb):1 (lambda)>
|
||||
irb(main):006:0> Fac = lambda{|f| lambda{|n| n < 2 ? 1 : n * f[n-1]}}
|
||||
=> #<Proc:0x00000202a88aa0@(irb):6 (lambda)>
|
||||
irb(main):007:0> Array.new(10) {|i| Y[Fac][i]}
|
||||
=> [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
|
||||
irb(main):008:0> Fib = lambda{|f| lambda{|n| n < 2 ? n : f[n-1] + f[n-2]}}
|
||||
=> #<Proc:0x00000201a968b8@(irb):8 (lambda)>
|
||||
irb(main):009:0> Array.new(10) {|i| Y[Fib][i]}
|
||||
=> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
|
||||
13
Task/Y-combinator/Ruby/y-combinator-2.rb
Normal file
13
Task/Y-combinator/Ruby/y-combinator-2.rb
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
def y(&f)
|
||||
lambda do |g|
|
||||
f.call {|*args| g[g][*args]}
|
||||
end.tap {|g| break g[g]}
|
||||
end
|
||||
|
||||
Fac = y {|&f| lambda {|n| n < 2 ? 1 : n * f[n - 1]}}
|
||||
Fib = y {|&f| lambda {|n| n < 2 ? n : f[n - 1] + f[n - 2]}}
|
||||
|
||||
p Array.new(10) {|i| Fac[i]}
|
||||
# => [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
|
||||
p Array.new(10) {|i| Fib[i]}
|
||||
# => [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
|
||||
7
Task/Y-combinator/Scala/y-combinator-1.scala
Normal file
7
Task/Y-combinator/Scala/y-combinator-1.scala
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
def Y[A,B](f: (A=>B)=>(A=>B)) = {
|
||||
case class W(wf: W=>A=>B) {
|
||||
def apply(w: W) = wf(w)
|
||||
}
|
||||
val g: W=>A=>B = w => f(w(w))(_)
|
||||
g(W(g))
|
||||
}
|
||||
5
Task/Y-combinator/Scala/y-combinator-2.scala
Normal file
5
Task/Y-combinator/Scala/y-combinator-2.scala
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
val fac = Y[Int, Int](f => i => if (i <= 0) 1 else f(i - 1) * i)
|
||||
fac(6) //> res0: Int = 720
|
||||
|
||||
val fib = Y[Int, Int](f => i => if (i < 2) i else f(i - 1) + f(i - 2))
|
||||
fib(6) //> res1: Int = 8
|
||||
27
Task/Y-combinator/Scheme/y-combinator.ss
Normal file
27
Task/Y-combinator/Scheme/y-combinator.ss
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
(define Y
|
||||
(lambda (f)
|
||||
((lambda (x) (x x))
|
||||
(lambda (g)
|
||||
(f (lambda args (apply (g g) args)))))))
|
||||
|
||||
(define fac
|
||||
(Y
|
||||
(lambda (f)
|
||||
(lambda (x)
|
||||
(if (< x 2)
|
||||
1
|
||||
(* x (f (- x 1))))))))
|
||||
|
||||
(define fib
|
||||
(Y
|
||||
(lambda (f)
|
||||
(lambda (x)
|
||||
(if (< x 2)
|
||||
x
|
||||
(+ (f (- x 1)) (f (- x 2))))))))
|
||||
|
||||
(display (fac 6))
|
||||
(newline)
|
||||
|
||||
(display (fib 6))
|
||||
(newline)
|
||||
3
Task/Y-combinator/Slate/y-combinator.slate
Normal file
3
Task/Y-combinator/Slate/y-combinator.slate
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
Method traits define: #Y &builder:
|
||||
[[| :f | [| :x | f applyWith: (x applyWith: x)]
|
||||
applyWith: [| :x | f applyWith: (x applyWith: x)]]].
|
||||
9
Task/Y-combinator/Smalltalk/y-combinator.st
Normal file
9
Task/Y-combinator/Smalltalk/y-combinator.st
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
Y := [:f| [:x| x value: x] value: [:g| f value: [:x| (g value: g) value: x] ] ].
|
||||
|
||||
fib := Y value: [:f| [:i| i <= 1 ifTrue: [i] ifFalse: [(f value: i-1) + (f value: i-2)] ] ].
|
||||
|
||||
(fib value: 10) displayNl.
|
||||
|
||||
fact := Y value: [:f| [:i| i = 0 ifTrue: [1] ifFalse: [(f value: i-1) * i] ] ].
|
||||
|
||||
(fact value: 10) displayNl.
|
||||
21
Task/Y-combinator/Standard-ML/y-combinator.ml
Normal file
21
Task/Y-combinator/Standard-ML/y-combinator.ml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
- datatype 'a mu = Roll of ('a mu -> 'a)
|
||||
fun unroll (Roll x) = x
|
||||
|
||||
fun fix f = (fn x => fn a => f (unroll x x) a) (Roll (fn x => fn a => f (unroll x x) a))
|
||||
|
||||
fun fac f 0 = 1
|
||||
| fac f n = n * f (n-1)
|
||||
|
||||
fun fib f 0 = 0
|
||||
| fib f 1 = 1
|
||||
| fib f n = f (n-1) + f (n-2)
|
||||
;
|
||||
datatype 'a mu = Roll of 'a mu -> 'a
|
||||
val unroll = fn : 'a mu -> 'a mu -> 'a
|
||||
val fix = fn : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b
|
||||
val fac = fn : (int -> int) -> int -> int
|
||||
val fib = fn : (int -> int) -> int -> int
|
||||
- List.tabulate (10, fix fac);
|
||||
val it = [1,1,2,6,24,120,720,5040,40320,362880] : int list
|
||||
- List.tabulate (10, fix fib);
|
||||
val it = [0,1,1,2,3,5,8,13,21,34] : int list
|
||||
2
Task/Y-combinator/Ursala/y-combinator-1.ursala
Normal file
2
Task/Y-combinator/Ursala/y-combinator-1.ursala
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
(r "f") "x" = "f"("f","x")
|
||||
my_fix "h" = r ("f","x"). ("h" r "f") "x"
|
||||
1
Task/Y-combinator/Ursala/y-combinator-2.ursala
Normal file
1
Task/Y-combinator/Ursala/y-combinator-2.ursala
Normal file
|
|
@ -0,0 +1 @@
|
|||
my_fix = //~&R+ ^|H\~&+ ; //~&R
|
||||
3
Task/Y-combinator/Ursala/y-combinator-3.ursala
Normal file
3
Task/Y-combinator/Ursala/y-combinator-3.ursala
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#import nat
|
||||
|
||||
fact = my_fix "f". ~&?\1! product^/~& "f"+ predecessor
|
||||
1
Task/Y-combinator/Ursala/y-combinator-4.ursala
Normal file
1
Task/Y-combinator/Ursala/y-combinator-4.ursala
Normal file
|
|
@ -0,0 +1 @@
|
|||
#fix my_fix
|
||||
1
Task/Y-combinator/Ursala/y-combinator-5.ursala
Normal file
1
Task/Y-combinator/Ursala/y-combinator-5.ursala
Normal file
|
|
@ -0,0 +1 @@
|
|||
fib = {0,1}?</1! sum+ fib~~+ predecessor^~/~& predecessor
|
||||
3
Task/Y-combinator/Ursala/y-combinator-6.ursala
Normal file
3
Task/Y-combinator/Ursala/y-combinator-6.ursala
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#cast %nLW
|
||||
|
||||
examples = (fact* <1,2,3,4,5,6,7,8>,fib* <1,2,3,4,5,6,7,8>)
|
||||
5
Task/Y-combinator/Ursala/y-combinator-7.ursala
Normal file
5
Task/Y-combinator/Ursala/y-combinator-7.ursala
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#import sol
|
||||
|
||||
#fix general_function_fixer 1
|
||||
|
||||
my_fix "h" = "h" my_fix "h"
|
||||
Loading…
Add table
Add a link
Reference in a new issue