Another update from ingydotnet^djgoku
This commit is contained in:
parent
91df62d461
commit
948b86eafa
7604 changed files with 108452 additions and 22726 deletions
13
Task/Y-combinator/C++/y-combinator-3.cpp
Normal file
13
Task/Y-combinator/C++/y-combinator-3.cpp
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
template <typename A, typename B>
|
||||
struct YFunctor {
|
||||
const std::function<std::function<B(A)>(std::function<B(A)>)> f;
|
||||
YFunctor(std::function<std::function<B(A)>(std::function<B(A)>)> _f) : f(_f) {}
|
||||
B operator()(A x) const {
|
||||
return f(*this)(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
std::function<B(A)> Y (std::function<std::function<B(A)>(std::function<B(A)>)> f) {
|
||||
return YFunctor<A,B>(f);
|
||||
}
|
||||
10
Task/Y-combinator/Elixir/y-combinator.elixir
Normal file
10
Task/Y-combinator/Elixir/y-combinator.elixir
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
iex(1)> yc = fn f -> (fn x -> x.(x) end).(fn y -> f.(fn arg -> y.(y).(arg) end) end) end
|
||||
#Function<6.90072148/1 in :erl_eval.expr/5>
|
||||
iex(2)> fac = fn f -> fn n -> if n < 2 do 1 else n * f.(n-1) end end end
|
||||
#Function<6.90072148/1 in :erl_eval.expr/5>
|
||||
iex(3)> for i <- 0..9, do: yc.(fac).(i)
|
||||
[1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
|
||||
iex(4)> fib = fn f -> fn n -> if n == 0 do 0 else (if n == 1 do 1 else f.(n-1) + f.(n-2) end) end end end
|
||||
#Function<6.90072148/1 in :erl_eval.expr/5>
|
||||
iex(5)> for i <- 0..9, do: yc.(fib).(i)
|
||||
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
|
||||
|
|
@ -1,53 +1,7 @@
|
|||
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 <A,B> Function<A,B> Y(Function<Function<A,B>, Function<A,B>> f) {
|
||||
return new Function<A,B>() {
|
||||
public B apply(A x) {
|
||||
return f.apply(this).apply(x);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,53 @@
|
|||
import java.util.function.Function;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SelfApplicable<OUTPUT> extends Function<SelfApplicable<OUTPUT>, OUTPUT> {
|
||||
public default OUTPUT selfApply() {
|
||||
return apply(this);
|
||||
}
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
import java.util.function.Function;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface FixedPoint<FUNCTION> extends Function<UnaryOperator<FUNCTION>, FUNCTION> {}
|
||||
public interface SelfApplicable<OUTPUT> extends Function<SelfApplicable<OUTPUT>, OUTPUT> {
|
||||
public default OUTPUT selfApply() {
|
||||
return apply(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,43 +1,5 @@
|
|||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
@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());
|
||||
}
|
||||
}
|
||||
public interface FixedPoint<FUNCTION> extends Function<UnaryOperator<FUNCTION>, FUNCTION> {}
|
||||
|
|
|
|||
|
|
@ -1,74 +1,43 @@
|
|||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Y<FUNCTION> extends SelfApplicable<FixedPoint<FUNCTION>> {
|
||||
public static void main(String... arguments) {
|
||||
BigInteger TWO = BigInteger.ONE.add(BigInteger.ONE);
|
||||
public interface VarargsFunction<INPUTS, OUTPUT> extends Function<INPUTS[], OUTPUT> {
|
||||
@SuppressWarnings("unchecked")
|
||||
public OUTPUT apply(INPUTS... inputs);
|
||||
|
||||
Function<Number, Long> toLong = Number::longValue;
|
||||
Function<Number, BigInteger> toBigInteger = toLong.andThen(BigInteger::valueOf);
|
||||
public static <INPUTS, OUTPUT> VarargsFunction<INPUTS, OUTPUT> from(Function<INPUTS[], OUTPUT> function) {
|
||||
return function::apply;
|
||||
}
|
||||
|
||||
/* 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();
|
||||
public static <INPUTS, OUTPUT> VarargsFunction<INPUTS, OUTPUT> upgrade(Function<INPUTS, OUTPUT> function) {
|
||||
return inputs -> function.apply(inputs[0]);
|
||||
}
|
||||
|
||||
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()))
|
||||
)
|
||||
)
|
||||
);
|
||||
public static <INPUTS, OUTPUT> VarargsFunction<INPUTS, OUTPUT> upgrade(BiFunction<INPUTS, INPUTS, OUTPUT> function) {
|
||||
return inputs -> function.apply(inputs[0], inputs[1]);
|
||||
}
|
||||
|
||||
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()))
|
||||
)
|
||||
)
|
||||
);
|
||||
@SuppressWarnings("unchecked")
|
||||
public default <POST_OUTPUT> VarargsFunction<INPUTS, POST_OUTPUT> andThen(
|
||||
VarargsFunction<OUTPUT, POST_OUTPUT> after) {
|
||||
return inputs -> after.apply(apply(inputs));
|
||||
}
|
||||
|
||||
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)
|
||||
);
|
||||
@SuppressWarnings("unchecked")
|
||||
public default Function<INPUTS, OUTPUT> toFunction() {
|
||||
return input -> apply(input);
|
||||
}
|
||||
|
||||
Map<String, VarargsFunction<Number, Number>> functions = new HashMap<>();
|
||||
functions.put("fibonacci", fibonacci);
|
||||
functions.put("factorial", factorial);
|
||||
functions.put("ackermann", ackermann);
|
||||
@SuppressWarnings("unchecked")
|
||||
public default BiFunction<INPUTS, INPUTS, OUTPUT> toBiFunction() {
|
||||
return (input, input2) -> apply(input, input2);
|
||||
}
|
||||
|
||||
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);
|
||||
@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());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,74 @@
|
|||
factorial[10] = 3628800
|
||||
ackermann[3, 2] = 29
|
||||
fibonacci[20] = 6765
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
3
Task/Y-combinator/Java/y-combinator-9.java
Normal file
3
Task/Y-combinator/Java/y-combinator-9.java
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
factorial[10] = 3628800
|
||||
ackermann[3, 2] = 29
|
||||
fibonacci[20] = 6765
|
||||
|
|
@ -12,3 +12,15 @@ function Y(f) {
|
|||
}));
|
||||
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;
|
||||
};
|
||||
});
|
||||
|
|
|
|||
5
Task/Y-combinator/JavaScript/y-combinator-5.js
Normal file
5
Task/Y-combinator/JavaScript/y-combinator-5.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
function Y(f) {
|
||||
return function() {
|
||||
return f(arguments.callee).apply(this, arguments);
|
||||
};
|
||||
}
|
||||
20
Task/Y-combinator/JavaScript/y-combinator-6.js
Normal file
20
Task/Y-combinator/JavaScript/y-combinator-6.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
let
|
||||
Y= // Except for the η-abstraction necessary for applicative order languages, this is the formal Y combinator.
|
||||
f=>((g=>(f((...x)=>g(g)(...x))))
|
||||
(g=>(f((...x)=>g(g)(...x))))),
|
||||
Y2= // Using β-abstraction to eliminate code repetition.
|
||||
f=>((f=>f(f))
|
||||
(g=>(f((...x)=>g(g)(...x))))),
|
||||
Y3= // Using β-abstraction to separate out the self application combinator δ.
|
||||
((δ=>f=>δ(g=>(f((...x)=>g(g)(...x)))))
|
||||
((f=>f(f)))),
|
||||
fix= // β/η-equivalent fix point combinator. Easier to convert to memoise than the Y combinator.
|
||||
(((f)=>(g)=>(h)=>(f(h)(g(h)))) // The Substitute combinator out of SKI calculus
|
||||
((f)=>(g)=>(...x)=>(f(g(g)))(...x)) // S((S(KS)K)S(S(KS)K))(KI)
|
||||
((f)=>(g)=>(...x)=>(f(g(g)))(...x))),
|
||||
fix2= // β/η-converted form of fix above into a more compact form
|
||||
f=>(f=>f(f))(g=>(...x)=>f(g(g))(...x)),
|
||||
opentailfact= // Open version of the tail call variant of the factorial function
|
||||
fact=>(n,m=1)=>n<2?m:fact(n-1,n*m);
|
||||
tailfact= // Tail call version of factorial function
|
||||
Y(parttailfact);
|
||||
9
Task/Y-combinator/JavaScript/y-combinator-7.js
Normal file
9
Task/Y-combinator/JavaScript/y-combinator-7.js
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
let
|
||||
polyfix= // A version that takes an array instead of multiple arguments would simply use l instead of (...l) for parameter
|
||||
(...l)=>(
|
||||
(f=>f(f))
|
||||
(g=>l.map(f=>(...x)=>f(...g(g))(...x)))),
|
||||
[even,odd]= // The new destructive assignment syntax for arrays
|
||||
polyfix(
|
||||
(even,odd)=>n=>(n===0)||odd(n-1),
|
||||
(even,odd)=>n=>(n!==0)&&even(n-1));
|
||||
|
|
@ -1 +1,6 @@
|
|||
Y = f -> (x -> x(x))(y -> f((args...) -> y(y)(args...)))
|
||||
julia> """
|
||||
# Y combinator
|
||||
|
||||
* `λf. (λx. f (x x)) (λx. f (x x))`
|
||||
"""
|
||||
Y = f -> (x -> x(x))(y -> f((t...) -> y(y)(t...)))
|
||||
|
|
|
|||
|
|
@ -1,2 +1,31 @@
|
|||
fac = f -> (n -> if n<2 1 else n*f(n-1) end)
|
||||
Y(fac)(3)
|
||||
julia> "# Factorial"
|
||||
fac = f -> (n -> n < 2 ? 1 : n * f(n - 1))
|
||||
|
||||
julia> "# Fibonacci"
|
||||
fib = f -> (n -> n == 0 ? 0 : (n == 1 ? 1 : f(n - 1) + f(n - 2)))
|
||||
|
||||
julia> [Y(fac)(i) for i = 1:10]
|
||||
10-element Array{Any,1}:
|
||||
1
|
||||
2
|
||||
6
|
||||
24
|
||||
120
|
||||
720
|
||||
5040
|
||||
40320
|
||||
362880
|
||||
3628800
|
||||
|
||||
julia> [Y(fib)(i) for i = 1:10]
|
||||
10-element Array{Any,1}:
|
||||
1
|
||||
1
|
||||
2
|
||||
3
|
||||
5
|
||||
8
|
||||
13
|
||||
21
|
||||
34
|
||||
55
|
||||
|
|
|
|||
|
|
@ -1,3 +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]] &];
|
||||
Y = Function[f, #[#] &[Function[g, f[g[g][##] &]]]];
|
||||
factorial = Y[Function[f, If[# < 1, 1, # f[# - 1]] &]];
|
||||
fibonacci = Y[Function[f, If[# < 2, #, f[# - 1] + f[# - 2]] &];
|
||||
|
|
|
|||
2
Task/Y-combinator/Moonscript/y-combinator.moon
Normal file
2
Task/Y-combinator/Moonscript/y-combinator.moon
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Z = (f using nil) -> ((x) -> x x) (x) -> f (...) -> (x x) ...
|
||||
factorial = Z (f using nil) -> (n) -> if n == 0 then 1 else n * f n - 1
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
sub Y (&f) { { .($_) }( -> &y { f({ y(&y)(&^arg) }) } ) }
|
||||
sub Y (&f) { { .($_) }( -> &y { f({ y(&y)($^arg) }) } ) }
|
||||
sub fac (&f) { sub ($n) { $n < 2 ?? 1 !! $n * f($n - 1) } }
|
||||
sub fib (&f) { sub ($n) { $n < 2 ?? $n !! f($n - 1) + f($n - 2) } }
|
||||
say map Y($_), ^10 for &fac, &fib;
|
||||
|
|
|
|||
|
|
@ -1,24 +1,22 @@
|
|||
/*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 !
|
||||
/*REXX program implements and displays a stateless Y combinator. */
|
||||
numeric digits 1000 /*allow big numbers. */
|
||||
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 factorial*/
|
||||
say ' fact' Y(fact (0 1 2 3 4 5 6 7 8 9 10 11)) /*single factorial*/
|
||||
say ' Dfact' Y(dfact (4 5 6 7 8 9 10 11 12 13)) /*double factorial*/
|
||||
say ' Tfact' Y(tfact (4 5 6 7 8 9 10 11 12 13)) /*triple factorial*/
|
||||
say ' Qfact' Y(qfact (4 5 6 7 8 40)) /*quadruple factorial*/
|
||||
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 numbers. */
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*────────────────────────────────────────────────────────────────────────────*/
|
||||
Y: parse arg Y _; $= /*the Y combinator.*/
|
||||
do j=1 for words(_); interpret '$=$' Y"("word(_,j)')'; end; return $
|
||||
fib: procedure; parse arg x; if x<2 then return x; s=0; a=0; b=1
|
||||
s=0; a=0; b=1; do j=2 to x; s=a+b; a=b; b=s; end; return s
|
||||
dfact: procedure; parse arg x; !=1; do j=x to 2 by -2; !=!*j; end; return !
|
||||
tfact: procedure; parse arg x; !=1; do j=x to 2 by -3; !=!*j; end; return !
|
||||
qfact: procedure; parse arg x; !=1; do j=x to 2 by -4; !=!*j; end; return !
|
||||
fact: procedure; parse arg x; !=1; do j=2 to x ; !=!*j; end; return !
|
||||
|
|
|
|||
|
|
@ -1,21 +1,44 @@
|
|||
enum Mu<T> { Roll(@fn(Mu<T>) -> T) }
|
||||
fn unroll<T>(Roll(f): Mu<T>) -> @fn(Mu<T>) -> T { f }
|
||||
use std::sync::Arc;
|
||||
use std::boxed::Box;
|
||||
use std::clone::Clone;
|
||||
|
||||
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))
|
||||
//Arc<Box<Closure>>
|
||||
#[macro_export]
|
||||
macro_rules! abc {
|
||||
($x:expr) => (Arc::new(Box::new($x)));
|
||||
}
|
||||
|
||||
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))));
|
||||
#[derive(Clone)]
|
||||
pub enum Mu<T> {
|
||||
Roll(Arc<Box<Fn(Mu<T>)->T>>),
|
||||
}
|
||||
|
||||
pub fn unroll<T>(Mu::Roll(f): Mu<T>) -> Arc<Box<Fn(Mu<T>)->T>> {f.clone()}
|
||||
|
||||
pub type Func<A, B> = Arc<Box<Fn(A)->B>>;
|
||||
pub type RecFunc<A, B> = Arc<Box<Fn(Func<A, B>) -> Func<A, B>>>;
|
||||
|
||||
pub fn y<A, B>(f: RecFunc<A, B>) -> Func<A, B> {
|
||||
let g:Arc<Box<Fn(Mu<Func<A, B>>)->Func<A, B>>> = abc!(move |x : Mu<Func<A, B>>| -> Func<A, B> {
|
||||
let f = f.clone();
|
||||
abc!(move |a:A| -> B {
|
||||
let f = f.clone();
|
||||
f(unroll(x.clone())(x.clone()))(a)
|
||||
})
|
||||
});
|
||||
g(Mu::Roll(g.clone()))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fib_test() {
|
||||
let fib : RecFunc<i32, i32> = abc!(|f| abc!(move |x| if (x<2) { 1 } else { f(x-1) + f(x-2)}));
|
||||
let b = y(fib)(10);
|
||||
assert_eq!(b, 89);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fac_test() {
|
||||
let fac : RecFunc<i32, i32> = abc!(|f| abc!(move |x| if (x==0) { 1 } else { f(x-1) * x }));
|
||||
let c = y(fac)(10);
|
||||
assert_eq!(c, 3628800);
|
||||
}
|
||||
|
|
|
|||
22
Task/Y-combinator/Vim-Script/y-combinator.vim
Normal file
22
Task/Y-combinator/Vim-Script/y-combinator.vim
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
" Translated from Python. Works with: Vim 7.0
|
||||
|
||||
func! Lambx(sig, expr, dict)
|
||||
let fanon = {'d': a:dict}
|
||||
exec printf("
|
||||
\func fanon.f(%s) dict\n
|
||||
\ return %s\n
|
||||
\endfunc",
|
||||
\ a:sig, a:expr)
|
||||
return fanon
|
||||
endfunc
|
||||
|
||||
func! Callx(fanon, arglist)
|
||||
return call(a:fanon.f, a:arglist, a:fanon.d)
|
||||
endfunc
|
||||
|
||||
let g:Y = Lambx('f', 'Callx(Lambx("x", "Callx(a:x, [a:x])", {}), [Lambx("y", ''Callx(self.f, [Lambx("...", "Callx(Callx(self.y, [self.y]), a:000)", {"y": a:y})])'', {"f": a:f})])', {})
|
||||
|
||||
let g:fac = Lambx('f', 'Lambx("n", "a:n<2 ? 1 : a:n * Callx(self.f, [a:n-1])", {"f": a:f})', {})
|
||||
|
||||
echo Callx(Callx(g:Y, [g:fac]), [5])
|
||||
echo map(range(10), 'Callx(Callx(Y, [fac]), [v:val])')
|
||||
Loading…
Add table
Add a link
Reference in a new issue