简体   繁体   中英

foldr confusion

I execute this statement on the interpreter

foldr (\x (a, b) -> if x == '_' then (a+1, [((div a 3), (mod a 3))] ++ b) else (a, b)) (0, []) "_______OX"

I expected the output to be

(7,[(0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2.0)])

however the output is

(7,[(2,0),(1,2),(1,1),(1,0),(0,2),(0,1),(0,0)])

what am I doing wrong. As far as I know, foldr starts from the last element of the list and my lambda function appends it to the beginning of the accumulator list. So I should get (0,0) as the first element. However, it's the opposite and I'm puzzled. :(

Also, a small question - How do I go about assigning tags for questions like these?

After 'X' you have

    (0,[])

After '0' you have

    (0,[])

After first '_' you have

    (1,[(0,0)])

After secont '_' you have

    (2,[(0,1),(0,0)]) -- you prepend in: [((div a 3), (mod a 3))] ++ b

After third '_' you have

    (3,[(O,2),(0,1),(0,0)])

...

Let's simplify this a bit, for better explanation:

foldr (\c (a,b) -> (a+1, a:b)) (0, []) "hi"

Foldr is defined as

foldr f a [] = a
foldr f a (x:xs) = f x (foldr f a xs)

Let us call the lambda function g Hence, the trace of the expression above:

g 'h' (foldr g (0,[]) "i") 
g 'h' (g 'i' (foldr g (0,[]) ""))
g 'h' (g 'i' (0, []))
g 'h' (1, [0])
(2, [1,0])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM