Skip to content

Instantly share code, notes, and snippets.

@m1el
Last active August 29, 2015 14:08
Show Gist options
  • Save m1el/95056d95ceecd4572892 to your computer and use it in GitHub Desktop.
Save m1el/95056d95ceecd4572892 to your computer and use it in GitHub Desktop.
// FizzBuzz in pure lambda notation
// transcribed from http://codon.com/programming-with-nothing
// props to http://community.bartdesmet.net/blogs/bart/archive/2009/08/17/mis-using-c-4-0-dynamic-type-free-lambda-calculus-church-numerals-and-more.aspx
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
using Fn = Func<dynamic, dynamic>;
class Program
{
static int to_int(Fn fn)
{
return fn(new Fn(x => x + 1))(0);
}
static bool to_bool(dynamic fn)
{
return fn(true)(false);
}
static List<object> to_list(Fn fn)
{
var list = new List<object>();
var LEFT = new Fn(p => p(new Fn(x => new Fn(y => x))));
var RIGHT = new Fn(p => p(new Fn(x => new Fn(y => y))));
var FIRST = new Fn(l => LEFT(RIGHT(l)));
var REST = new Fn(l => RIGHT(RIGHT(l)));
while (!to_bool(LEFT(fn)))
{
list.Add(FIRST(fn));
fn = REST(fn);
}
return list;
}
static string to_string(Fn fn)
{
var str = "";
var alpha = "0123456789BFiuz";
foreach (var c in to_list(fn))
{
str += alpha[to_int((Fn)c)];
}
return str;
}
static void Main(string[] args)
{
var ZERO = new Fn(f => new Fn(x => x));
var ONE = new Fn(f => new Fn(x => f(x)));
var TWO = new Fn(f => new Fn(x => f(f(x))));
var THREE = new Fn(f => new Fn(x => f(f(f(x)))));
var FOUR = new Fn(f => new Fn(x => f(f(f(f(x))))));
var FIVE = new Fn(f => new Fn(x => f(f(f(f(f(x)))))));
var INC = new Fn(n => new Fn(p => new Fn(x => p(n(p)(x)))));
var DEC = new Fn(n => new Fn(f => new Fn(x => n(new Fn(g => new Fn(h => h(g(f)))))(new Fn(u => x))(new Fn(u => u)))));
var PLUS = new Fn(m => new Fn(n => new Fn(f => new Fn(x => m(f)(n(f)(x))))));
var MINUS = new Fn(m => new Fn(n => n(DEC)(m)));
var MUL = new Fn(m => new Fn(n => new Fn(f => n(m(f)))));
var POW = new Fn(m => new Fn(n => n(m)));
var FIFTEEN = MUL(FIVE)(THREE);
var HUNDRED = MUL(MUL(FIVE)(FIVE))(FOUR);
var FALSE = new Fn(a => new Fn(b => b));
var TRUE = new Fn(a => new Fn(b => a));
var IF = new Fn(b => new Fn(x => new Fn(y => b(x)(y))));
var IS_ZERO = new Fn(n => n(new Fn(x => FALSE))(TRUE));
var LEQ = new Fn(m => new Fn(n => IS_ZERO(MINUS(m)(n))));
var Z = new Fn(f => new Fn(x => f(new Fn(y => x(x)(y))))
(new Fn(x => f(new Fn(y => x(x)(y))))));
var MOD = Z(new Fn(f => new Fn(m => new Fn(n =>
IF(LEQ(n)(m))
(new Fn(x => f(MINUS(m)(n))(n)(x)))
(m)))));
var PAIR = new Fn(x => new Fn(y => new Fn(f => f(x)(y))));
var LEFT = new Fn(p => p(new Fn(x => new Fn(y => x))));
var RIGHT = new Fn(p => p(new Fn(x => new Fn(y => y))));
var EMPTY = PAIR(TRUE)(TRUE);
var UNSHIFT = new Fn(l => new Fn(x => PAIR(FALSE)(PAIR(x)(l))));
var IS_EMPTY = LEFT;
var FIRST = new Fn(l => LEFT(RIGHT(l)));
var REST = new Fn(l => RIGHT(RIGHT(l)));
var RANGE =
Z(new Fn(f => new Fn(m => new Fn(n =>
IF(LEQ(m)(n))
(new Fn(x => UNSHIFT(f(INC(m))(n))(m)(x)))
(EMPTY)
))));
var FOLD =
Z(new Fn(f => new Fn(l => new Fn(x => new Fn(g =>
IF(IS_EMPTY(l))
(x)
(new Fn(y =>
g(f(REST(l))(x)(g))(FIRST(l))(y))))))));
var MAP =
new Fn(k => new Fn(f =>
FOLD(k)(EMPTY)
(new Fn(l => new Fn(x => UNSHIFT(l)(f(x)))))));
var TEN = MUL(TWO)(FIVE);
var B = TEN;
var F = INC(B);
var I = INC(F);
var U = INC(I);
var ZED = INC(U);
var FIZZ = UNSHIFT(UNSHIFT(UNSHIFT(UNSHIFT(EMPTY)(ZED))(ZED))(I))(F);
var BUZZ = UNSHIFT(UNSHIFT(UNSHIFT(UNSHIFT(EMPTY)(ZED))(ZED))(U))(B);
var FIZZBUZZ = UNSHIFT(UNSHIFT(UNSHIFT(UNSHIFT(BUZZ)(ZED))(ZED))(I))(F);
var DIV = Z(new Fn(f => new Fn(m => new Fn(n =>
IF(LEQ(n)(m))
(new Fn(x => INC(f(MINUS(m)(n))(n))(x)))
(ZERO)))));
var PUSH =
new Fn(l => new Fn(x =>
FOLD(l)(UNSHIFT(EMPTY)(x))(UNSHIFT)));
var TO_DIGITS =
Z(new Fn(f => new Fn(n =>
PUSH(
IF(LEQ(n)(DEC(TEN)))
(EMPTY)
(new Fn(x => f(DIV(n)(TEN))(x)))
)(MOD(n)(TEN)))));
var result = MAP(RANGE(ONE)(HUNDRED))(new Fn(n =>
IF(IS_ZERO(MOD(n)(FIFTEEN)))
(FIZZBUZZ)
(IF(IS_ZERO(MOD(n)(THREE)))
(FIZZ)
(IF(IS_ZERO(MOD(n)(FIVE)))
(BUZZ)
(TO_DIGITS(n))))
));
foreach (var row in to_list(result))
{
Console.WriteLine(to_string((Fn)row));
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment