I am familiar with defining the ADD function on top of the SUCC function, such as in the following:
const ONE = f => a => f(a);
const SUCC = n => f => a => f(n(f)(a)); // SUCC = λnfa.f(nfa)
const ADD = n1 => n2 => n1(SUCC)(n2); // ADD = λnk.n SUCC k
console.log(ADD(ONE)(ONE)(x => x+1)(0));
// 2
However, how would I define add if there wasn’t a successor function already defined? I tried using substitution to get the following, but I’m not sure why it’s not working. What do I have screwed up here?
const ONE = f => a => f(a);
const ADD = n1 => n2 => f => a => n1(f(n1(f)(a)))(n2);
console.log(ADD(ONE)(ONE)(x => x+1)(0));
// TypeError: f is not a function
>Solution :
const ADD = n1 => n2 => n1(n => f => a => f(n(f)(a)))(n2)
// ADD = λnk.n (λnfa.f (n f a)) k
When doing substitution, you simply replace the term to be substituted with its definition:
n1 => n2 => n1(SUCC)(n2)- definition of
SUCC:n => f => a => f(n(f)(a)) - replace
SUCCwith the above definition:n1 => n2 => n1(n => f => a => f(n(f)(a)))(n2)
Another way you could define ADD is like this:
const ADD = n1 => n2 => f => x => n1(f)(n2(f)(x))
// ADD = λnkfx.n f (k f x)