簡體   English   中英

javascript中的y-combinator

[英]y-combinator in javascript

我已經在js中建立了一個y-combinator

const y = f => { const g = self => x => f(self(self))(x); return g(g);}

我這樣簡化了這段代碼

 const y = f => { const g = self => f(self(self)); return g(g);}

這得到了無限遞歸。 這兩個版本有什么區別?

如果您不了解兩者之間的區別,那么您實際上構建了它們,我會感到驚訝。 然而,證明兩者之間差異的最好方法是遵循他們的評估。

const y = f => {
  const g = self => x => f(self(self))(x)
  return g(g)
}

y (z) ...
// (self => x => z(self(self))(x)) (self => x => z(self(self))(x)) ...
// returns:
// x => z((self => x1 => z(self(self))(x1))(self => x2 => z(self(self))(x2)))(x)

好的,所以y(z) (其中z是某個函數,沒關系)返回一個函數x => ... 在我們應用功能之前,評估到此為止。

現在,將其與您的第二個定義進行比較

const y = f => {
  const g = self => f(self(self))
  return g(g)
}

y (z) ...
// (self => z(self(self))) (self => z(self(self)))
// z((self => z(self(self)))(self => z(self(self)))) ...
// z(z((self => z(self(self)))(self => z(self(self))))) ...
// z(z(z((self => z(self(self)))(self => z(self(self)))))) ...
// z(z(z(z((self => z(self(self)))(self => z(self(self))))))) ...
// ... and on and on

因此y (z)永遠不會終止-至少在使用應用順序評估的JavaScript中-在應用調用函數之前先評估函數參數


備用Y組合器

在這里,我們可以從頭開始構建一個Y組合器

// standard definition
const Y = f => f (Y (f))

// prevent immediate infinite recursion in applicative order language (JS)
const Y = f => f (x => Y (f) (x))

// remove reference to self using U combinator
const U = f => f (f)
const Y = U (h => f => f (x => h (h) (f) (x)))

讓我們測試一下

 const U = f => f (f) const Y = U (h => f => f (x => h (h) (f) (x))) // range :: Int -> Int -> [Int] const range = Y (f => acc => x => y => x > y ? acc : f ([...acc,x]) (x + 1) (y)) ([]) // fibonacci :: Int -> Int const fibonacci = Y (f => a => b => x => x === 0 ? a : f (b) (a + b) (x - 1)) (0) (1) console.log(range(0)(10).map(fibonacci)) // [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ] 

或我最近的最愛

 // simplified Y const Y = f => x => f (Y (f)) (x) // range :: Int -> Int -> [Int] const range = Y (f => acc => x => y => x > y ? acc : f ([...acc,x]) (x + 1) (y)) ([]) // fibonacci :: Int -> Int const fibonacci = Y (f => a => b => x => x === 0 ? a : f (b) (a + b) (x - 1)) (0) (1) console.log(range(0)(10).map(fibonacci)) // [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ] 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM