Projection functions,例如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çš„æ–¹å¼æ¥é€’归定义广义投影函数呢?
ç”案 0 :(得分:0)
所有投影函数都å¯ä»¥åˆ†è§£ä¸ºä»¥ä¸‹ä¸‰ä¸ªç»„åˆå™¨ï¼š
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"
我将ä¿ç•™å®ƒä½œä¸ºç»ƒä¹ ,让您了解æ¤å‡½æ•°çš„ä¾èµ–类型。