static void Main(params String[] arguments) { BigInteger TWO = BigInteger.One + BigInteger.One; Func <IFormattable, long> toLong = x => long.Parse(x.ToString()); Func <IFormattable, BigInteger> toBigInteger = x => new BigInteger(toLong(x)); /* Based on https://gist.github.com/aruld/3965968/#comment-604392 */ Y <VarargsFunction <IFormattable, IFormattable> > combinator = y => f => x => f(y.selfApply()(f))(x); FixedPoint <VarargsFunction <IFormattable, IFormattable> > fixedPoint = combinator.Cast <SelfApplicable <FixedPoint <VarargsFunction <IFormattable, IFormattable> > > >().selfApply(); VarargsFunction <IFormattable, IFormattable> fibonacci = fixedPoint( f => VarargsFunction.upgrade( toBigInteger.andThen( n => (IFormattable)( (n.CompareTo(TWO) <= 0) ? 1 : BigInteger.Parse(f(n - BigInteger.One).ToString()) + BigInteger.Parse(f(n - TWO).ToString())) ) ) ); VarargsFunction <IFormattable, IFormattable> factorial = fixedPoint( f => VarargsFunction.upgrade( toBigInteger.andThen( n => (IFormattable)((n.CompareTo(BigInteger.One) <= 0) ? 1 : n * BigInteger.Parse(f(n - BigInteger.One).ToString())) ) ) ); VarargsFunction <IFormattable, IFormattable> ackermann = fixedPoint( f => VarargsFunction.upgrade( (BigInteger m, BigInteger n) => m.Equals(BigInteger.Zero) ? n + BigInteger.One : f( m - BigInteger.One, n.Equals(BigInteger.Zero) ? BigInteger.One : f(m, n - BigInteger.One) ) ).transformArguments(toBigInteger) ); var functions = new Dictionary <String, VarargsFunction <IFormattable, IFormattable> >(); functions.Add("fibonacci", fibonacci); functions.Add("factorial", factorial); functions.Add("ackermann", ackermann); var parameters = new Dictionary <VarargsFunction <IFormattable, IFormattable>, IFormattable[]>(); parameters.Add(functions["fibonacci"], new IFormattable[] { 20 }); parameters.Add(functions["factorial"], new IFormattable[] { 10 }); parameters.Add(functions["ackermann"], new IFormattable[] { 3, 2 }); functions.AsParallel().Select( entry => entry.Key + "[" + String.Join(", ", parameters[entry.Value].Select(x => x.ToString())) + "]" + " = " + entry.Value(parameters[entry.Value]) ).ForAll(Console.WriteLine); }
public static VarargsFunction <PRE_INPUTS, OUTPUT> transformArguments <PRE_INPUTS, INPUTS, OUTPUT>( this VarargsFunction <INPUTS, OUTPUT> @this, Func <PRE_INPUTS, INPUTS> transformer) { return(inputs => @this(inputs.AsParallel().AsOrdered().Select(transformer).ToArray())); }
public static Func <INPUTS, OUTPUT> toFunction <INPUTS, OUTPUT>( this VarargsFunction <INPUTS, OUTPUT> @this) { return(input => @this(input)); }
public static Func <INPUTS, INPUTS, OUTPUT> toBiFunction <INPUTS, OUTPUT>( this VarargsFunction <INPUTS, OUTPUT> @this) { return((input, input2) => @this(input, input2)); }
public static VarargsFunction <INPUTS, POST_OUTPUT> andThen <INPUTS, OUTPUT, POST_OUTPUT>( this VarargsFunction <INPUTS, OUTPUT> @this, VarargsFunction <OUTPUT, POST_OUTPUT> after) { return(inputs => after(@this(inputs))); }