closure
前言
最近看 JS 時看到 closure,在 Haskell 中也有一樣的字
JavaScriopt
從理論來說,所有函數都是 closure
從實作角度來說
符合下列兩個其中之一的
- 用了自由變數
- 即使創建他的上下文已經銷毀,他仍然存在
用了自由變數
const name = "Heisenberg"
function sayMyName() {
console.log(name); // Heisenberg
}
sayMyName();
name
在 sayMyName
這個 function 外面,卻可以在 sayMyName
這個 function 裡面拿到他的值。
創建他的上下文已經銷毀,他仍然存在
在函數裡面 return
function outer() {
outerVar = '外層變數';
function inner () {
console.log(outerVar)
}
return inner;
}
innerFunc = outer();
innerFunc();
另一個例子
function compose (f, g) {
return function (x) {
return f ( g(x) );
}
}
Haskell
Haskell Wiki 對 closure 的定義
A closure, the opposite of a combinator, is a function that makes use of free variables in its definition. It ‘closes’ around some portion of its environment.
combinator 是沒有 free variable 的 function 或定義
而 closure 是他的相反,是有 free variable 的
f x = (\y -> x + y)
f returns a closure, because the variable x, which is bound outside of the lambda abstraction is used inside its definition.
An interesting side note: the context in which x was bound shouldn’t even exist anymore, and wouldn’t, had the lambda abstraction not closed around x.
f . g = \x -> f ( g(x) )
在 $\lambda x$ 中,f 和 g 沒有被定義,他們是 自由變數(free variables),他們的定義由上層函數提供。
跑到這裡時,會用上層函數提供的環境把它「封閉」起來,包進自己的 function scope ($ \lambda x $
) 中。
由 外層函數 提供 內層函數 中 自由變數 的 閉包。