This commit is contained in:
Ingy döt Net 2013-10-27 22:24:23 +00:00
parent 6f050a029e
commit 776bba907c
3887 changed files with 59894 additions and 7280 deletions

View file

@ -19,10 +19,10 @@ 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
@ -37,11 +37,11 @@ End Type
'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)
@ -52,11 +52,11 @@ 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)]))
@ -66,11 +66,11 @@ 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
@ -86,11 +86,11 @@ End Type
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)
@ -101,7 +101,7 @@ 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)
@ -116,11 +116,11 @@ End Type
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)
@ -131,7 +131,7 @@ 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

View file

@ -1,44 +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))
)
&
( ( 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))
)
&
)

View file

@ -0,0 +1 @@
Y = (f) -> g = f( (t...) -> g(t...) )

View file

@ -0,0 +1 @@
Y = (f) -> ((h)->h(h))((h)->f((t...)->h(h)(t...)))

View file

@ -0,0 +1,2 @@
fac = Y( (f) -> (n) -> if n > 1 then n * f(n-1) else 1 )
fib = Y( (f) -> (n) -> if n > 1 then f(n-1) + f(n-2) else n )

View file

@ -26,6 +26,6 @@ void main() { // Demo code --------------------
return self(m - 1, self(m, n - 1));
});
writeln("factorial: ", map!factorial(iota(10)));
writeln("factorial: ", 10.iota.map!factorial);
writeln("ackermann(3, 5): ", ackermann(3, 5));
}

View file

@ -0,0 +1,27 @@
Y f:
labda y:
labda:
call y @y
f
labda x:
x @x
call
labda f:
labda n:
if < 1 n:
* n f -- n
else:
1
set :fac Y
labda f:
labda n:
if < 1 n:
+ f - n 2 f -- n
else:
1
set :fib Y
. fac 6
. fib 6

View file

@ -1,142 +1,8 @@
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;
import java.util.function.Function;
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));
@FunctionalInterface
public interface SelfApplicable<OUTPUT> extends Function<SelfApplicable<OUTPUT>, OUTPUT> {
public default OUTPUT selfApply() {
return apply(this);
}
}

View file

@ -1,147 +1,5 @@
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;
import java.util.function.UnaryOperator;
@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);
}
}
public interface FixedPoint<FUNCTION> extends Function<UnaryOperator<FUNCTION>, FUNCTION> {}

View file

@ -1,3 +1,43 @@
factorial[10] = 3628800
ackermann[3, 2] = 29
fibonacci[20] = 6765
import java.util.Arrays;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.BiFunction;
@FunctionalInterface
public interface VarargsFunction<INPUTS, OUTPUT> extends Function<INPUTS[], OUTPUT> {
@SuppressWarnings("unchecked")
public OUTPUT apply(INPUTS... inputs);
public static <INPUTS, OUTPUT> VarargsFunction<INPUTS, OUTPUT> from(Function<INPUTS[], OUTPUT> function) {
return function::apply;
}
public static <INPUTS, OUTPUT> VarargsFunction<INPUTS, OUTPUT> upgrade(Function<INPUTS, OUTPUT> function) {
return inputs -> function.apply(inputs[0]);
}
public static <INPUTS, OUTPUT> VarargsFunction<INPUTS, OUTPUT> upgrade(BiFunction<INPUTS, INPUTS, OUTPUT> function) {
return inputs -> function.apply(inputs[0], inputs[1]);
}
@SuppressWarnings("unchecked")
public default <POST_OUTPUT> VarargsFunction<INPUTS, POST_OUTPUT> andThen(
VarargsFunction<OUTPUT, POST_OUTPUT> after) {
return inputs -> after.apply(apply(inputs));
}
@SuppressWarnings("unchecked")
public default Function<INPUTS, OUTPUT> toFunction() {
return input -> apply(input);
}
@SuppressWarnings("unchecked")
public default BiFunction<INPUTS, INPUTS, OUTPUT> toBiFunction() {
return (input, input2) -> apply(input, input2);
}
@SuppressWarnings("unchecked")
public default <PRE_INPUTS> VarargsFunction<PRE_INPUTS, OUTPUT> transformArguments(Function<PRE_INPUTS, INPUTS> transformer) {
return inputs -> apply((INPUTS[]) Arrays.stream(inputs).parallel().map(transformer).toArray());
}
}

View file

@ -0,0 +1,74 @@
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import java.util.stream.LongStream;
@FunctionalInterface
public interface Y<FUNCTION> extends SelfApplicable<FixedPoint<FUNCTION>> {
public static void main(String... arguments) {
BigInteger TWO = BigInteger.ONE.add(BigInteger.ONE);
Function<Number, Long> toLong = Number::longValue;
Function<Number, BigInteger> toBigInteger = toLong.andThen(BigInteger::valueOf);
/* Based on https://gist.github.com/aruld/3965968/#comment-604392 */
Y<VarargsFunction<Number, Number>> combinator = y -> f -> x -> f.apply(y.selfApply().apply(f)).apply(x);
FixedPoint<VarargsFunction<Number, Number>> fixedPoint = combinator.selfApply();
VarargsFunction<Number, Number> fibonacci = fixedPoint.apply(
f -> VarargsFunction.upgrade(
toBigInteger.andThen(
n -> (n.compareTo(TWO) <= 0)
? 1
: new BigInteger(f.apply(n.subtract(BigInteger.ONE)).toString())
.add(new BigInteger(f.apply(n.subtract(TWO)).toString()))
)
)
);
VarargsFunction<Number, Number> factorial = fixedPoint.apply(
f -> VarargsFunction.upgrade(
toBigInteger.andThen(
n -> (n.compareTo(BigInteger.ONE) <= 0)
? 1
: n.multiply(new BigInteger(f.apply(n.subtract(BigInteger.ONE)).toString()))
)
)
);
VarargsFunction<Number, Number> ackermann = fixedPoint.apply(
f -> VarargsFunction.upgrade(
(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, VarargsFunction<Number, Number>> functions = new HashMap<>();
functions.put("fibonacci", fibonacci);
functions.put("factorial", factorial);
functions.put("ackermann", ackermann);
Map<VarargsFunction<Number, Number>, Number[]> parameters = new HashMap<>();
parameters.put(functions.get("fibonacci"), new Number[]{20});
parameters.put(functions.get("factorial"), new Number[]{10});
parameters.put(functions.get("ackermann"), new Number[]{3, 2});
functions.entrySet().stream().parallel().map(
entry -> entry.getKey()
+ Arrays.toString(parameters.get(entry.getValue()))
+ " = "
+ entry.getValue().apply(parameters.get(entry.getValue()))
).forEach(System.out::println);
}
}

View file

@ -0,0 +1,3 @@
factorial[10] = 3628800
ackermann[3, 2] = 29
fibonacci[20] = 6765

View file

@ -1,7 +1,11 @@
function pseudoY(f) {
return function g() {
return f.apply(g, arguments);
};
return (function(h) {
return h(h);
})(function(h) {
return f.bind(function() {
return h(h).apply(null, arguments);
});
});
}
var fac = pseudoY(function(n) {

View file

@ -0,0 +1,20 @@
<?php
function pseudoY($f) {
$g = function($w) use ($f) {
return $f->bindTo(function() use ($w) {
return call_user_func_array($w($w), func_get_args());
});
};
return $g($g);
}
$factorial = pseudoY(function($n) {
return $n > 1 ? $n * $this($n - 1) : 1;
});
echo $factorial(10), "\n";
$fibonacci = pseudoY(function($n) {
return $n > 1 ? $this($n - 1) + $this($n - 2) : $n;
});
echo $fibonacci(10), "\n";
?>

View file

@ -1,5 +1,4 @@
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;
say map Y($_), ^10 for &fac, &fib;

View file

@ -1,5 +1,14 @@
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";
sub Y { my $f = shift; # λf.
sub { my $x = shift; $x->($x) }->( # (λx.x x)
sub {my $y = shift; $f->(sub {$y->($y)(@_)})} # λy.f λz.y y z
)
}
my $fac = sub {my $f = shift;
sub {my $n = shift; $n < 2 ? 1 : $n * $f->($n-1)}
};
my $fib = sub {my $f = shift;
sub {my $n = shift; $n == 0 ? 0 : $n == 1 ? 1 : $f->($n-1) + $f->($n-2)}
};
for my $f ($fac, $fib) {
print join(' ', map Y($f)->($_), 0..9), "\n";
}

View file

@ -0,0 +1,8 @@
#lang lazy
(define Y (λ(f)((λ(x)(f (x x)))(λ(x)(f (x x))))))
(define Fact
(Y (λ(fact) (λ(n) (if (zero? n) 1 (* n (fact (- n 1))))))))
(define Fib
(Y (λ(fib) (λ(n) (if (<= n 1) n (+ (fib (- n 1)) (fib (- n 2))))))))

View file

@ -0,0 +1,3 @@
#lang racket
(define Y (λ(b)((λ(f)(b(λ(x)((f f) x))))
(λ(f)(b(λ(x)((f f) x)))))))

View file

@ -0,0 +1,17 @@
#lang typed/racket
(: make-recursive : (All (S T) ((S -> T) -> (S -> T)) -> (S -> T)))
(define-type Tau (All (S T) (Rec this (this -> (S -> T)))))
(define (make-recursive f)
((lambda: ([x : (Tau S T)]) (f (lambda (z) ((x x) z))))
(lambda: ([x : (Tau S T)]) (f (lambda (z) ((x x) z))))))
(: fact : Number -> Number)
(define fact (make-recursive
(lambda: ([fact : (Number -> Number)])
(lambda: ([n : Number])
(if (zero? n)
1
(* n (fact (- n 1))))))))
(fact 5)

View file

@ -0,0 +1,21 @@
enum Mu<T> { Roll(@fn(Mu<T>) -> T) }
fn unroll<T>(Roll(f): Mu<T>) -> @fn(Mu<T>) -> T { f }
type RecFunc<A, B> = @fn(@fn(A) -> B) -> @fn(A) -> B;
fn fix<A, B>(f: RecFunc<A, B>) -> @fn(A) -> B {
let g: @fn(Mu<@fn(A) -> B>) -> @fn(A) -> B =
|x| |a| f(unroll(x)(x))(a);
g(Roll(g))
}
fn main() {
let fac: RecFunc<uint, uint> =
|f| |x| if (x==0) { 1 } else { f(x-1) * x };
let fib : RecFunc<uint, uint> =
|f| |x| if (x<2) { 1 } else { f(x-1) + f(x-2) };
let ns = std::vec::from_fn(20, |i| i);
println(fmt!("%?", ns.map(|&n| fix(fac)(n))));
println(fmt!("%?", ns.map(|&n| fix(fib)(n))));
}