8

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'变成了一个重击,但我无法在我的脑海中推理。

作为上下文,我正在查看Y组合器,它应该找到函数的固定点,所以如果我有这个函数one x = 1,那么 fix one == 1必须保持,对吗?

所以fix one = let {x = one x} in x,但我看不出1会如何出现。

4

1 回答 1

12

谈到 let,我认为 letP = Q in R会评估Q -> Q'thenP被替换为Q'in R,或者:R[P -> Q']

从道德上讲,是的,但P不会立即评估,而是在需要时进行评估。

但是在修复定义中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一定要持有,对吧?

是的。

所以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

只需扩展定义。保留递归定义,以防您再次需要它们。

于 2020-12-03T10:40:18.050 回答