Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
|
|
@ -1,4 +1,5 @@
|
|||
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.
|
||||
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]].
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ struct RecursiveFunc {
|
|||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
std::function<B(A)> fix (std::function<std::function<B(A)>(std::function<B(A)>)> f) {
|
||||
std::function<B(A)> Y (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) {
|
||||
|
|
@ -35,8 +35,8 @@ FuncFunc almost_fib = [](Func f) {
|
|||
};
|
||||
|
||||
int main() {
|
||||
auto fib = fix(almost_fib);
|
||||
auto fac = fix(almost_fac);
|
||||
auto fib = Y(almost_fib);
|
||||
auto fac = Y(almost_fac);
|
||||
std::cout << "fib(10) = " << fib(10) << std::endl;
|
||||
std::cout << "fac(10) = " << fac(10) << std::endl;
|
||||
return 0;
|
||||
6
Task/Y-combinator/C++/y-combinator-2.cpp
Normal file
6
Task/Y-combinator/C++/y-combinator-2.cpp
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
template <typename A, typename B>
|
||||
std::function<B(A)> Y (std::function<std::function<B(A)>(std::function<B(A)>)> f) {
|
||||
return [f](A x) {
|
||||
return f(Y(f))(x);
|
||||
};
|
||||
}
|
||||
|
|
@ -18,8 +18,8 @@
|
|||
(otherwise (+ (funcall f (- n 1))
|
||||
(funcall f (- n 2)))))))
|
||||
|
||||
? ((mapcar (y #'fac) '(1 2 3 4 5 6 7 8 9 10))
|
||||
? (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))
|
||||
? (mapcar (Y #'fib) '(1 2 3 4 5 6 7 8 9 10))
|
||||
(1 1 2 3 5 8 13 21 34 55)
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@ type FuncFunc func(Func) Func
|
|||
type RecursiveFunc func (RecursiveFunc) Func
|
||||
|
||||
func main() {
|
||||
fac := fix(almost_fac)
|
||||
fib := fix(almost_fib)
|
||||
fac := Y(almost_fac)
|
||||
fib := Y(almost_fib)
|
||||
fmt.Println("fac(10) = ", fac(10))
|
||||
fmt.Println("fib(10) = ", fib(10))
|
||||
}
|
||||
|
||||
func fix(f FuncFunc) Func {
|
||||
func Y(f FuncFunc) Func {
|
||||
g := func(r RecursiveFunc) Func {
|
||||
return f(func(x int) int {
|
||||
return r(r)(x)
|
||||
5
Task/Y-combinator/Go/y-combinator-2.go
Normal file
5
Task/Y-combinator/Go/y-combinator-2.go
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
func Y(f FuncFunc) Func {
|
||||
return func(x int) int {
|
||||
return f(Y(f))(x)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +1,25 @@
|
|||
fix :: (a -> a) -> a
|
||||
fix f = f (fix f)
|
||||
fix f = f (fix f) -- _not_ the {fix f = x where x = f x}
|
||||
|
||||
fac :: Integer -> Integer
|
||||
fac' f n | n <= 0 = 1
|
||||
fac_ f n | n <= 0 = 1
|
||||
| otherwise = n * f (n-1)
|
||||
fac = fix fac'
|
||||
fac = fix fac_ -- fac_ (fac_ . fac_ . fac_ . 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'
|
||||
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))
|
||||
fibs_ a = 0:1:(fix zipP a (tail a))
|
||||
where
|
||||
zipP f (x:xs) (y:ys) = x+y : f xs ys
|
||||
fibs = fix fibs'
|
||||
fibs = fix fibs_
|
||||
|
||||
-- This code shows how the functions can be used:
|
||||
main = do
|
||||
|
|
|
|||
|
|
@ -1,53 +1,25 @@
|
|||
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));
|
||||
}
|
||||
import java.util.function.Function;
|
||||
|
||||
public interface YCombinator {
|
||||
interface RecursiveFunction<F> extends Function<RecursiveFunction<F>, F> { }
|
||||
public static <A,B> Function<A,B> Y(Function<Function<A,B>, Function<A,B>> f) {
|
||||
RecursiveFunction<Function<A,B>> r = w -> f.apply(x -> w.apply(w).apply(x));
|
||||
return r.apply(r);
|
||||
}
|
||||
|
||||
public static void main(String... arguments) {
|
||||
Function<Integer,Integer> fib = Y(f -> n ->
|
||||
(n <= 2)
|
||||
? 1
|
||||
: (f.apply(n - 1) + f.apply(n - 2))
|
||||
);
|
||||
Function<Integer,Integer> fac = Y(f -> n ->
|
||||
(n <= 1)
|
||||
? 1
|
||||
: (n * f.apply(n - 1));
|
||||
);
|
||||
|
||||
System.out.println("fib(10) = " + fib.apply(10));
|
||||
System.out.println("fac(10) = " + fac.apply(10));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,3 @@
|
|||
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 <A,B> Function<A,B> Y(Function<Function<A,B>, Function<A,B>> f) {
|
||||
return x -> f.apply(Y(f)).apply(x);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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-8.java
Normal file
3
Task/Y-combinator/Java/y-combinator-8.java
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
factorial[10] = 3628800
|
||||
ackermann[3, 2] = 29
|
||||
fibonacci[20] = 6765
|
||||
|
|
@ -1,18 +1,14 @@
|
|||
function Y(f) {
|
||||
var g = f(function() {
|
||||
return g.apply(this, arguments);
|
||||
});
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,14 +1,9 @@
|
|||
function Y(f) {
|
||||
var g = f((function(h) {
|
||||
return function() {
|
||||
var g = f(h(h));
|
||||
return g.apply(this, arguments);
|
||||
}
|
||||
return (function(h) {
|
||||
return h(h);
|
||||
})(function(h) {
|
||||
return function() {
|
||||
var g = f(h(h));
|
||||
return g.apply(this, arguments);
|
||||
}
|
||||
}));
|
||||
return g;
|
||||
return f(function() {
|
||||
return h(h).apply(this, arguments);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,17 @@
|
|||
function Y(f) {
|
||||
function pseudoY(f) {
|
||||
return (function(h) {
|
||||
return h(h);
|
||||
})(function(h) {
|
||||
return f(function() {
|
||||
return h(h).apply(this, arguments);
|
||||
return f.bind(function() {
|
||||
return h(h).apply(null, 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;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,17 +1,5 @@
|
|||
function pseudoY(f) {
|
||||
return (function(h) {
|
||||
return h(h);
|
||||
})(function(h) {
|
||||
return f.bind(function() {
|
||||
return h(h).apply(null, arguments);
|
||||
});
|
||||
});
|
||||
function Y(f) {
|
||||
return function() {
|
||||
return f(Y(f)).apply(this, 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;
|
||||
});
|
||||
|
|
|
|||
1
Task/Y-combinator/Julia/y-combinator-1.julia
Normal file
1
Task/Y-combinator/Julia/y-combinator-1.julia
Normal file
|
|
@ -0,0 +1 @@
|
|||
Y = f -> (x -> x(x))(y -> f((args...) -> y(y)(args...)))
|
||||
2
Task/Y-combinator/Julia/y-combinator-2.julia
Normal file
2
Task/Y-combinator/Julia/y-combinator-2.julia
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
fac = f -> (n -> if n<2 1 else n*f(n-1) end)
|
||||
Y(fac)(3)
|
||||
|
|
@ -4,33 +4,32 @@ typedef int (^Func)(int);
|
|||
typedef Func (^FuncFunc)(Func);
|
||||
typedef Func (^RecursiveFunc)(id); // hide recursive typing behind dynamic typing
|
||||
|
||||
Func fix (FuncFunc f) {
|
||||
Func Y(FuncFunc f) {
|
||||
RecursiveFunc r =
|
||||
^(id y) {
|
||||
RecursiveFunc w = y; // cast value back into desired type
|
||||
return f(^(int x) {
|
||||
return w(w)(x);
|
||||
});
|
||||
};
|
||||
^(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[]) {
|
||||
@autoreleasepool {
|
||||
|
||||
FuncFunc almost_fac = ^Func(Func f) {
|
||||
return ^(int n) {
|
||||
if (n <= 1) return 1;
|
||||
return n * f(n - 1);
|
||||
};
|
||||
};
|
||||
|
||||
FuncFunc almost_fib = ^Func(Func f) {
|
||||
Func fib = Y(^Func(Func f) {
|
||||
return ^(int n) {
|
||||
if (n <= 2) return 1;
|
||||
return f(n - 1) + f(n - 2);
|
||||
};
|
||||
};
|
||||
});
|
||||
Func fac = Y(^Func(Func f) {
|
||||
return ^(int n) {
|
||||
if (n <= 1) return 1;
|
||||
return n * f(n - 1);
|
||||
};
|
||||
});
|
||||
|
||||
Func fib = fix(almost_fib);
|
||||
Func fac = fix(almost_fac);
|
||||
5
Task/Y-combinator/Objective-C/y-combinator-2.m
Normal file
5
Task/Y-combinator/Objective-C/y-combinator-2.m
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Func Y(FuncFunc f) {
|
||||
return ^(int x) {
|
||||
return f(Y(f))(x);
|
||||
};
|
||||
}
|
||||
5
Task/Y-combinator/PARI-GP/y-combinator.pari
Normal file
5
Task/Y-combinator/PARI-GP/y-combinator.pari
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Y(f)=x->f(f,x);
|
||||
fact=Y((f,n)->if(n,n*f(f,n-1),1));
|
||||
fib=Y((f,n)->if(n>1,f(f,n-1)+f(f,n-2),n));
|
||||
apply(fact, [1..10])
|
||||
apply(fib, [1..10])
|
||||
|
|
@ -1,26 +1,5 @@
|
|||
<?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);
|
||||
return function() use($f) {
|
||||
return call_user_func_array($f(Y($f)), func_get_args());
|
||||
};
|
||||
}
|
||||
|
||||
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";
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -1,20 +1,26 @@
|
|||
<?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);
|
||||
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);
|
||||
}
|
||||
|
||||
$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;
|
||||
});
|
||||
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";
|
||||
?>
|
||||
|
|
|
|||
20
Task/Y-combinator/PHP/y-combinator-4.php
Normal file
20
Task/Y-combinator/PHP/y-combinator-4.php
Normal 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";
|
||||
?>
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
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) } }
|
||||
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;
|
||||
|
|
|
|||
3
Task/Y-combinator/Perl/y-combinator-2.pl
Normal file
3
Task/Y-combinator/Perl/y-combinator-2.pl
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
sub Y { my $f = shift;
|
||||
sub {$f->(Y($f))->(@_)}
|
||||
}
|
||||
1
Task/Y-combinator/Python/y-combinator-2.py
Normal file
1
Task/Y-combinator/Python/y-combinator-2.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
Y = lambda f: lambda *args: f(Y(f))(*args)
|
||||
|
|
@ -1,13 +1,9 @@
|
|||
def y(&f)
|
||||
lambda do |g|
|
||||
f.call {|*args| g[g][*args]}
|
||||
end.tap {|g| break g[g]}
|
||||
end
|
||||
y = ->(f) {->(g) {g.(g)}.(->(g) { f.(->(*args) {g.(g).(*args)})})}
|
||||
|
||||
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]}}
|
||||
fac = ->(f) { ->(n) { n < 2 ? 1 : n * f.(n-1) } }
|
||||
|
||||
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]
|
||||
p 10.times.map {|i| y.(fac).(i)}
|
||||
|
||||
fib = ->(f) { ->(n) { n < 2 ? n : f.(n-2) + f.(n-1) } }
|
||||
|
||||
p 10.times.map {|i| y.(fib).(i)}
|
||||
|
|
|
|||
13
Task/Y-combinator/Ruby/y-combinator-3.rb
Normal file
13
Task/Y-combinator/Ruby/y-combinator-3.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]
|
||||
3
Task/Y-combinator/Ruby/y-combinator-4.rb
Normal file
3
Task/Y-combinator/Ruby/y-combinator-4.rb
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
y = lambda do |f|
|
||||
lambda {|*args| f[y[f]][*args]}
|
||||
end
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
(define Y
|
||||
(lambda (f)
|
||||
(lambda (h)
|
||||
((lambda (x) (x x))
|
||||
(lambda (g)
|
||||
(f (lambda args (apply (g g) args)))))))
|
||||
(h (lambda args (apply (g g) args)))))))
|
||||
|
||||
(define fac
|
||||
(Y
|
||||
3
Task/Y-combinator/Scheme/y-combinator-2.ss
Normal file
3
Task/Y-combinator/Scheme/y-combinator-2.ss
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
(define Y
|
||||
(lambda (h)
|
||||
(lambda args (apply (h (Y h)) args))))
|
||||
1
Task/Y-combinator/Smalltalk/y-combinator-2.st
Normal file
1
Task/Y-combinator/Smalltalk/y-combinator-2.st
Normal file
|
|
@ -0,0 +1 @@
|
|||
Y := [:f| [:x| (f value: (Y value: f)) value: x] ].
|
||||
1
Task/Y-combinator/Standard-ML/y-combinator-2.ml
Normal file
1
Task/Y-combinator/Standard-ML/y-combinator-2.ml
Normal file
|
|
@ -0,0 +1 @@
|
|||
fun fix f x = f (fix f) x
|
||||
Loading…
Add table
Add a link
Reference in a new issue