2016-08-22 67 views
1

聲稱JavaScript是一種功能性語言,但它肯定不像一個。它缺乏使功能語言簡潔的大部分內容,其中之一就是免費的風格。 幸運的是我們有箭頭的功能和代理在ES6,所以我把它在我自己實現一點自由的風格與代理:濫用高級代理濫用

let pfree = ctx => f => new Proxy (f, { 
    has: (t, p) => p in t || p in ctx 
, get: (t, p) => { 
    let k = p in t? t[p]: ctx[p]; 

    if (k instanceof Function) return (
     function fetch (_k) { 
     return pfree (ctx) (x => (q => q instanceof Function 
             ? fetch (q) 
             : t (q) 
           ) (_k(x)) 
          ) 
     })(k); 

    return k; 
    } 
}); 

正好headace,但它確實在對的NodeJS求職,你可以使用它像這樣:

let p = pfree (global) (x => x) 

with (p) { 
    add = x => y => x + y 
    succ = add (1) 
    five = succ . add (2) . succ (1) 
} 

console.log(five) // 5 

當你做出更高階的功能出現問題:

with (p) { 
    flip = f => x => y => f (y) (x) 
    Const = a => b => a 
    dot = f => a => b => f(a(b)) 
    ap = f => g => x => f (x) (g (x)) 

    zero = flip (Const) 
    succ = ap (dot) 

    num = n => n (x => x + 1) (0) // The number n is represented by running a function n times over some input 

    console.log (num (succ (succ (succ (zero))))) // 3 
    console.log (num . succ . succ . succ (zero)) // [Function] 
} 

而且我真的不能換我周圍的頭爲什麼..

想法?

+0

請注意,您可以免費使用點式即使沒有圓點組成:-) – Bergi

+0

@Bergi'點(SUCC)(點(SUCC)(SUCC) )'和'succ不太一樣。 succ。 succ' – BlackCap

+0

當然,但它具有可用JavaScript的優點,而不是代理濫用:-)我喜歡這些思想實驗,但對於實際使用,您寧願將Haskell編譯爲JS。 – Bergi

回答

4

的問題很簡單:

succ . add(2) 

無法區分

(succ . add) (2) 

與JavaScript屬性的訪問規則,但你希望他們做不同的事情。

的解決方案是不可能的(我敢說),但你也許可以通過引入一個自定義分組操作來解決:

group(succ . add) (2) 

你也應該分配給調用的p屬性。你應該能夠作出如下工作:

addFour = succ . add (2) . succ 
five = group(succ . add (2) . succ) (1) 
fiveAgain = addFour (1) 

console.log (group(num . succ . succ . succ) (zero)) // 3