Skip to content

Instantly share code, notes, and snippets.

@matarillo
Last active August 7, 2020 04:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matarillo/9eb530d8ca02a2ce9d1c0b20f8313ba2 to your computer and use it in GitHub Desktop.
Save matarillo/9eb530d8ca02a2ce9d1c0b20f8313ba2 to your computer and use it in GitHub Desktop.
using System;
class Program
{
static void Main(string[] args)
{
int fib40 = Fix<int, Func<int, Func<int, int>>>(fib => f1 => f2 => n => n == 0 ? f1 : fib(f2)(f1 + f2)(n - 1))(0)(1)(40);
Console.WriteLine(fib40);
int fib40z = Z<int, Func<int, Func<int, int>>>(fib => f1 => f2 => n => n == 0 ? f1 : fib(f2)(f1 + f2)(n - 1))(0)(1)(40);
Console.WriteLine(fib40z);
}
// name 'Fix' is recursive
static Func<T1, T2> Fix<T1, T2>(Func<Func<T1, T2>, Func<T1, T2>> f) =>
f(x => (Fix(f))(x));
// type 'Recursive<T1, T2>' is recursive
static Func<T1, T2> Z<T1, T2>(Func<Func<T1, T2>, Func<T1, T2>> f) =>
((Recursive<T1, T2>)(g => f(x => g(g)(x))))
((Recursive<T1, T2>)(g => f(x => g(g)(x))));
}
delegate Func<T1, T2> Recursive<T1, T2>(Recursive<T1, T2> f);
// Fixed-Point Combinator
let rec fix f =
f (fun x -> fix f x)
let fib40 =
fix (fun fib f1 f2 n -> if n = 0 then f1 else fib f2 (f1 + f2) (n - 1)) 0 1 40
printfn "%d" fib40
// Z Combinator
type Recursive<'a, 'b> =
delegate of Recursive<'a, 'b> -> ('a -> 'b)
let z f =
(Recursive(fun g -> f (fun x -> g.Invoke g x))).Invoke
(Recursive(fun g -> f (fun x -> g.Invoke g x)))
let fib40z =
z (fun fib f1 f2 n -> if n = 0 then f1 else fib f2 (f1 + f2) (n - 1)) 0 1 40
printfn "%d" fib40z
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment