2016-08-22 3 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, но он делает job- в 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 
Смежные вопросы