id
( 1 P 1 ) 和const
( 2 P 1 )等投影函数在函数式编程中非常有用。但是,有时您需要更复杂的投影函数,例如5 P 4。您可以用点式的方式手动编写它,a => b => c => d => e => d
但这很乏味且可读性不强。因此,能够改写会更好proj(5)(4)
。以下是我目前在 JavaScript 中定义这个广义投影函数的方式:
const proj = n => m => curry(n, (...args) => args[m - 1]);
const curry = (n, f, args = []) => n > 0 ?
x => curry(n - 1, f, args.concat([x])) :
f(...args);
console.log(proj(5)(4)("a")("b")("c")("d")("e")); // prints "d"
如您所见,这种实现proj
是一种 hack,因为它使用了可变参数。因此,它不能直接翻译成 Agda 或 Idris 之类的语言(由于依赖类型,广义投影函数实际上是可类型化的)。那么,如何递归地定义一个广义投影函数,使其可以直接翻译成 Agda 呢?