所有投影函数可以分解为以下三个组合:
I :: a -> a
I x = x
K :: a -> b -> a
K x y = x
C :: (a -> c) -> a -> b -> c
C f x y = f x
使用这三个组合词,我们可以定义如下各种投影函数:
âââââââ¬âââââââââââ¬âââââââââââ¬âââââââââââ¬âââââââââââ¬ââââââââââââââ
â n\m â 1 â 2 â 3 â 4 â 5 â
âââââââ¼âââââââââââ¼âââââââââââ¼âââââââââââ¼âââââââââââ¼ââââââââââââââ¤
â 1 â I â â â â â
â 2 â K â KI â â â â
â 3 â CK â KK â K(KI) â â â
â 4 â C(CK) â K(CK) â K(KK) â K(K(KI)) â â
â 5 â C(C(CK)) â K(C(CK)) â K(K(CK)) â K(K(KK)) â K(K(K(KI))) â
âââââââ´âââââââââââ´âââââââââââ´âââââââââââ´âââââââââââ´ââââââââââââââ
如您所见,这里有一个递归模式:
proj 1 1 = I
proj n 1 = C (proj (n - 1) 1)
proj n m = K (proj (n - 1) (m - 1))
请注意
K = CI
这就是为什么
proj 2 1
作品。将其直接转换为JavaScript:
const I = x => x;
const K = x => y => x;
const C = f => x => y => f(x);
const raise = (Error, msg) => { throw new Error(msg); };
const proj = n => n === 1 ?
m => m === 1 ? I : raise(RangeError, "index out of range") :
m => m === 1 ? C(proj(n - 1)(1)) : K(proj(n - 1)(m - 1));
console.log(proj(5)(4)("a")("b")("c")("d")("e")); // prints "d"
我将把它作为练习留给您,让您了解这个函数的依赖类型。