折叠混乱

时间:2013-03-07 23:13:12

标签: list haskell lambda

我在解释器上执行此语句

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

我预计输出为

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

然而输出是

(7,[(2,0),(1,2),(1,1),(1,0),(0,2),(0,1),(0,0)])
我在做错了什么。据我所知,foldr从列表的最后一个元素开始,我的lambda函数将它附加到累加器列表的开头。所以我应该得到(0,0)作为第一个元素。然而,情况正好相反,我很困惑。 :(

另外,一个小问题 - 如何为这些问题分配标签?

2 个答案:

答案 0 :(得分:2)

'X'后你有

    (0,[])

在'0'之后你有

    (0,[])

首先'_'后你有

    (1,[(0,0)])

在secont'_'后你有

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

在第三个'_'之后你有

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

...

答案 1 :(得分:0)

让我们稍微简化一下,以获得更好的解释:

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

Foldr定义为

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

让我们调用lambda函数g 因此,上面表达式的痕迹:

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])