What optimization method does ghci use to speed up the recursive map?

Let's say I have the following function:

minc = map (+1)
natural = 1:minc natural

It seems to unfold as follows:

1:minc(1:minc(1:minc(1:minc(1:minc(1:minc(1:minc(1:minc(1:minc(1:minc...
1:2:minc(minc(1:minc(1:minc(1:minc(1:minc(1:minc(1:minc(1:minc(1:minc...
1:2:minc(2:minc(2:minc(2:minc(2:minc(2:minc(2:minc(2:minc(2:minc(minc...
1:2:3:minc(3:minc(3:minc(3:minc(3:minc(3:minc(3:minc(3:minc(minc(minc...
...                                                                

Although it is lazily evaluated, to create each new number nin the list, you need to expand the expression nonce, which gives us complexity O(N^2). But by runtime, I see that the real complexity is still linear!

What kind of optimization does Haskell use in this case, and how does it expose this expression?

+4
source share
2 answers

The list of naturals is divided between each recursive step. The graph is calculated as follows.

1:map (+1) _
 ^         |
 `---------'

1: (2 : map (+1) _)
      ^          |
      `----------'

1: (2 : (3 : map (+1) _)
           ^          |
           `----------'

, O (n), O (N ^ 2).

+5

n n , O (N 2).

. N O (N 2) -, [1]. N- , :

(!!n) $ 1:minc(1:minc(1:minc(1:minc(1:minc(1:minc(1:minc(1:minc(1:minc...
(!!n-1) $ minc(1:minc(1:minc(1:minc(1:minc(1:minc(1:minc(1:minc(1:minc...
(!!n-1) $ (1+1):minc(minc(1:minc(1:minc(1:minc(1:minc(1:minc(1:minc(1:minc...
            -- note that `(1+1)` isn't actually calculated!
(!!n-2) $ minc(minc(1:minc(1:minc(1:minc(1:minc(1:minc(1:minc(1:minc...
(!!n-2) $ ((1+1)+1):minc(minc(minc(1:minc(1:minc(1:minc(1:minc(1:minc(1:minc...
            -- again, neither of the additions is actually calculated.
(!!n-3) $ minc(minc(minc(1:minc(1:minc(1:minc(1:minc(1:minc(1:minc...
(!!n-3) $ ((...)+1):minc(minc(minc(minc(1:minc(1:minc(1:minc(1:minc(1:minc...
...
(!!n-n) $ ((...+1)+1) : minc(minc(...minc(minc(1:minc(...
           ╰─ n ─╯
(!!0) $ (n+1) : _
n+1

N, N , – O (N) .

, map . , .. _:_ thunk, , 1, .

, , minc(minc(...(minc(1 : ..., (... + 1) : minc(... .


[1] , N , O (N). , .

+2

All Articles