What does “floated out” mean?

前端 未结 2 1641
别跟我提以往
别跟我提以往 2020-12-29 22:56

On the Haskell wiki I read that this:

fib =
    let fib\' 0 = 0
        fib\' 1 = 1
        fib\' n = fib (n - 1) + fib (n - 2)
    in  (map fib\' [0 ..] !!)         


        
2条回答
  •  时光说笑
    2020-12-29 23:15

    It's not a very good explanation.

    "Floated out" simply means that in:

    \x -> let y = ... in z
    

    if ... does not mention x then it can be floated out of the lambda:

    let y = ... in \x -> z
    

    which means it will only be computed once,1 which could save a lot of time if ... is expensive. However, GHC is conservative about performing optimisations like this, since they can introduce space leaks. (Though it does do so for the second definition if you give it a type signature, as Daniel Fischer points out in his answer.)

    This isn't about automatic optimisation, though. The first snippet defines fib' outside of the lambda, whereas the second defines it inside (the lambda is implicit in fib x = ..., which is equivalent to fib = \x -> ...), which is what the quote is saying.

    Even that's not really relevant, however; what's relevant is that in the first snippet, map fib' [0 ..] occurs outside the lambda, and so its result is shared among all applications of the lambda (in that code, the "lambda" arises from the partial application of (!!)). In the latter, it's inside the lambda, and so likely to be recomputed for every application of fib.

    The end result is that the former implementation caches the values and so is far more efficient than the latter. Note that the first snippet's efficiency is dependent on the fact that fib' doesn't recurse directly, but instead through fib, and therefore benefits from the memoisation.

    It's related to eta-expansion; the latter snippet is an eta-expansion of the first. But the statement you quoted doesn't explain what's going on at all.

    1 Note that this is implementation-specific behaviour, and not part of Haskell's semantics. However, all reasonable implementations will behave in this manner.

提交回复
热议问题