I have a function prefixes that, given [1, 2, 3], returns the prefixes [[1], [1, 2], [1, 2, 3]]. It is defined as follows:
prefixes :: Num a => [a] -> [[a]]
prefixes = foldr (\x acc -> [x] : (map ((:) x) acc)) []
I have spent nearly two days trying to understand why this works. When I debug this in my head, I imagine this for prefixes [1, 2, 3]:
foldr call|__________________________________________________________________________
1 | [1] : (map ((:) 1) [])
|
| where x = 1 and acc = []
| returns acc = [[1]]
|
2 | [2] : (map ((:) 2) [[1]])
|
| where x = 2 and acc = [[1]]
| and (map ((:) 2) [[1]])
| returns acc = [[1, 2]]
| and [2] : [[1, 2]]
| returns [[2], [1, 2]]
|
3 | [3] : (map ((:) 3) [[2], [1, 2]])
|
| where x = 3 and acc = [[2], [1, 2]]
| and (map ((:) 3) [[2], [1, 2]])
| returns acc = [[2, 3], [1, 2, 3]]
| and [3] : [[2, 3], [1, 2, 3]]
| returns [[3], [2, 3], [1, 2, 3]]
|
And then the function terminates and returns [[3], [2, 3], [1, 2, 3]]. But obviously that is not happening. It returns [[1], [1, 2], [1, 2, 3]].
In Ghci, I find this:
Stopped in Main.prefixes, ex.hs:21:20-63
_result :: [a] -> [[a]] = _
[ex.hs:21:20-63] *Main> :step
Stopped in Main.prefixes, ex.hs:21:37-59
_result :: [[Integer]] = _
acc :: [[Integer]] = _
x :: Integer = 1
[ex.hs:21:37-59] *Main> :step
[[1]
Stopped in Main.prefixes, ex.hs:21:44-58
_result :: [[Integer]] = _
acc :: [[Integer]] = _
x :: Integer = 1
[ex.hs:21:44-58] *Main> :step
Stopped in Main.prefixes, ex.hs:21:37-59
_result :: [[Integer]] = _
acc :: [[Integer]] = _
x :: Integer = 2
[ex.hs:21:37-59] *Main> :step
,
Stopped in Main.prefixes, ex.hs:21:49-53
_result :: [Integer] -> [Integer] = _
x :: Integer = 1
[ex.hs:21:49-53] *Main> :step
[1,2]
Stopped in Main.prefixes, ex.hs:21:44-58
_result :: [[Integer]] = _
acc :: [[Integer]] = _
x :: Integer = 2
[ex.hs:21:44-58] *Main> :step
Stopped in Main.prefixes, ex.hs:21:37-59
_result :: [[Integer]] = _
acc :: [[Integer]] = _
x :: Integer = 3
[ex.hs:21:37-59] *Main> :step
,
[1Stopped in Main.prefixes, ex.hs:21:49-53
_result :: [Integer] -> [Integer] = _
x :: Integer = 2
[ex.hs:21:49-53] *Main> :step
,2,3]
Stopped in Main.prefixes, ex.hs:21:44-58
_result :: [[Integer]] = _
acc :: [[Integer]] = _
x :: Integer = 3
[ex.hs:21:44-58] *Main> :step
]
Which I interpret as:
__lines___|__________________________________________________________________________
21:37-59 | [1] : (map ((:) 1) acc) -> [[1]
|
|
|
21:44-58 | (map ((:) 1) acc) -> does nothing, as acc = []
|
|
|
21:37-59 | [2] : (map ((:) 2) acc) -> ,
|
|
|
21:49-53 | ((:) 1) -> [1, 2]
|
|
|
21:44-58 | (map ((:) 2) acc) -> outputs nothing
|
|
|
21:37-59 | [3] : (map ((:) 3) acc) -> ,[1
|
|
|
21:49-53 | ((:) 2) -> , 2, 3]
|
|
21:44-58 | (map ((:) 3) acc) -> ]
|
Printing [[1], [1, 2], [1, 2, 3]]. Could someone explain why, when lines 49-53 are evaluated, x is the x value from the previous foldr invocation?
I know that (map ((:) x) acc) can be expanded to (foldr ((:) . ((:) x)) [] acc), as map f = foldr ((:) . f) []. So I rewrote the function into the following
prefixesSolution :: Num a => [a] -> [[a]]
prefixesSolution = foldr (\x acc -> [x] : (foldr ((:) . ((:) x)) [] acc)) []
And this works as well. Now, the lambda passed to the second foldr ((:) . ((:) x)) I would imagine could be refactored as (\ element accumulator -> (element:accumulator) . ((element:accumulator) x)). But this does not work: Couldn't match expected type ‘a -> a0 -> b0’ with actual type ‘[[a]]’. All this I have done in order to pinpoint exactly what is happening.
I also do not understand the function passed to map ((:) x).
I apologize for how convoluted this post is. At this point I don't even know what I don't know. If someone could clearly walk me through this function I would be so so grateful.