如何评估x中的“fixf=let{x=fx}”?
fix f = let {x = f x} in x
谈到let,我认为这let P = Q in R会评估 Q -> Q' 然后 P 被 R 中的 Q' 替换,或者:R[P -> Q']。
但是在fix定义上Q取决于R,那么如何评估?
我想这是关于懒惰的评估。Q' 变成了一个 thunk,但我无法在我的脑海中推理。
就上下文而言,我正在查看Y组合子,它应该找到一个函数的不动点,所以如果我有这个函数one x = 1,那么 fix one == 1必须保持,对吗?
所以fix one = let {x = one x} in x,但我看不出如何1从中出现。
回答
说到 let ,我以为 let
P = Q in R会评估Q -> Q'thenP被Q'inR或:替换R[P -> Q']。
从道德上讲,是的,但P不会立即进行评估,而是在需要时进行评估。
但是在 fix 定义中
Q取决于R,那么如何评估呢?
Q不靠R,靠P。这使得P依赖于它自己,递归。这可能会导致几种不同的结果。粗略地说:
-
如果
Q在计算之前不能返回其结果的任何部分P,则P表示无限递归计算,该计算不会终止。例如,let x = x + 1 in x -- loops forever with no result -- (GHC is able to catch this specific case and raise an exception instead, -- but it's an irrelevant detail) -
如果
Q可以在需要评估之前返回其结果的一部分P,它会这样做。let x = 2 : x in x -- x = 2 : .... can be generated immediately -- This results in the infinite list 2:2:2:2:2:..... let x = (32, 10 + fst x) in x -- x = (32, ...) can be generated immediately -- hence x = (32, 10 + fst (32, ...)) = (32, 10+32) = (32, 42)
我想这是关于懒惰的评估。
Q'变成了一个重击,但我无法在脑海中推理。
P与 thunk 相关联。重要的是这个 thunk 是否在返回输出的某些部分之前调用自己。
就上下文而言,我正在查看 Y 组合器,它应该找到一个函数的不动点,所以如果我有这个函数。
one x = 1,那么fix one == 1一定要hold住吧?
是的。
所以
fix one = let x = one x in x,但我不明白为什么1会出现
我们可以这样计算:
fix one
= {- definition of fix -}
let x = one x in x
= {- definition of x -}
let x = one x in one x
= {- definition of one -}
let x = one x in 1
= {- x is now irrelevant -}
1
只需扩展定义。保留递归定义,以防您再次需要它们。