Combinators
Eric Lippert writes about a limitation of generic delegates in that they cannot be used to build combinators — a function that takes a function and returns a function. With nongeneric delegate one can define a combinator as follows:
delegate D D(D d);
Eric then demonstrates some combinators from combinatory logic. I thought that there were better examples from lambda calculus. Here are definitions of some Church numerals in which we express any number n as a higher-order function that applies another function f n times.
D N0 = f => x => x;
D N1 = f => x => f(x)
D N2 = f => x => f(f(x))Func<int,D> NGEN = i => i == 0 ? N0 : SUCC( NGEN( i – 1) )
Below are some arithmetic and logical operations:
D SUCC = n => f => x => n(f(x))
D PLUS = m => n => f => x => m(f(n(f(x)))
D MULT = m => n => f => m(n(f))D FALSE = x => y => y
D TRUE = x => y => xD IF = c => x => y => c(x)(y)
D AND = p => q => p(q)(FALSE)
D OR = p => q => p(TRUE)(q)
D NOT = p => p(FALSE)(TRUE)