2013-03-07 2 views
0

я исполню это заявление на переводчикаfoldr путаницы

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 начинается с последнего элемента списка, и моя функция лямбда добавляет его в начало списка аккумуляторов. Поэтому я должен получить (0,0) как первый элемент. Однако, это наоборот, и я озадачен. :(

Кроме того, маленький вопрос? - Как я могу идти о назначении тегов на вопросы, подобные этим

+0

Если '(0, 0) 'был первым элементом * добавил * в список, то это было бы быть последним элементом * списка *. Это то, о чем вы смущены? – Pubby

+0

Для лучшей читаемости вы всегда можете заменить '[a] ++ b' на' a: b' или '(a): b' (в зависимости от формы a, но в большинстве случаев это просто' a'). Кроме того, '((a), (b))' всегда может быть ** записано '(a, b)' – Ingo

+0

@pubby, да. не является ли элемент, который сначала считывается, становясь последним элементом в конечном списке? – shashydhar

ответ

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) 

Назовем функцию лямбда 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]) 
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)]) 

...