kb 17.10.2012 13:30 04a3831c

Да уж, ленивость окончательно запутывает и так непростую ситуацию с foldl и foldr. Приходится ломать мозги.

Получается, что, в классическом варианте, когда вы проходите по всему списку, то (по возможности) лучше использовать foldl', т.к. хвостовая рекурсия и всё такое.

С другой стороны, в виду ленивости, foldr имеет возможность прервать свою работу когда ему необходимо, при этом не вычисляя foldr хвоста.

Или здесь я тоже где-то ошибаюсь? :)

1. 0xd34df00d 17.10.2012 13:31 Azoth_primary

Какого хвоста? foldr идет справа.

2. kb0xd34df00d /1 17.10.2012 13:34

ну, хвоста — в смысле "остатка".

3. kb0xd34df00d /1 17.10.2012 13:38

о, ты тоже попался, выходит. нифига оно не с хвоста идёт, а вполне с головы. просто если функция делает вычисления, учитывая аккумулятор, то он тоже вычисляется и т.п.

в результате, вот это:

findKey :: (Eq k) => k → [(k,v)] → Maybe v
findKey key = foldr (\(k,v) acc → if key == k then Just v else acc) Nothing

очень даже эффективно работает, никакого хвоста не дёргая.

4. 0xd34df00dkb /3 17.10.2012 13:41 Azoth_primary

Prelude> let a = [1, 2, 3]
Prelude> (foldl (-) 0 a, foldr (-) 0 a)
(-6,2)

5. kb0xd34df00d /4 17.10.2012 13:43

да, но только это не "оно идёт справа", а "оно подставляет аккумулятор вправо / влево". а "идёт" оно как раз всегда слева направо.

6. kb0xd34df00d /4 17.10.2012 13:43

ну, то есть, это ваше "справа" и "слева" — это просто порядок аргументов к функции твоей и не более.

7. 0xd34df00dkb /5 17.10.2012 13:43 Azoth_primary

Ну блядь.
http://zvon.org/other/haskell/Outputprel...
it takes the second argument and the last item of the list and applies the function, then it takes the penultimate item from the end and the result, and so on. See scanr for intermediate results.
> the last item

8. 0xd34df00d0xd34df00d /7 17.10.2012 13:44 Azoth_primary

Читай внимательно сорсы foldr, там вполне видно, что идет оно именно справа налево.

9. kb0xd34df00d /7 17.10.2012 13:44

нахуй мне твои тексты, вот исходник

-- if the list is empty, the result is the initial value z; else
-- apply f to the first element and the result of folding the rest
foldr f z [] = z
foldr f z (x:xs) = f x (foldr f z xs)

-- if the list is empty, the result is the initial value; else
-- we recurse immediately, making the new initial value the result
-- of combining the old initial value with the first element.
foldl f z [] = z
foldl f z (x:xs) = foldl f (f z x) xs

10. 0xd34df00dkb /9 17.10.2012 13:45 Azoth_primary

А теперь подумай, что выполнится сначала, f x (foldr f z xs) или foldr f z xs. Вопрос глупый, да.

11. kb0xd34df00d /8 17.10.2012 13:45

> (x:xs)
> справа налево

12. 0xd34df00dkb /11 17.10.2012 13:45 Azoth_primary

Ты неправильно читаешь исходник.

13. DZhon 17.10.2012 13:49 STARGATE

Все правильно. foldr в ленивом режиме, foldl — в энергичном.

14. kb0xd34df00d /12 17.10.2012 13:50

ну еще раз. соль (которую я еле допёр) в том, что

*Main> findKey 1 (map (\x → (x, x)) [1..10000000000000000000000000])

сработает мгновенно, т.к. в этом здоровом списке он возьмёт только первый элемент. если ты будешь делать findKey 2, то возьмутся первых два элемента. это я и называю "слева направо".

15. kbDZhon /13 17.10.2012 13:51

Не надо меня троллить :(

16. DZhonkb /15 17.10.2012 13:52 STARGATE

wut?

17. 0xd34df00dkb /14 17.10.2012 13:52 Azoth_primary

Если твоя f из foldr такова, что ее можно заэвалюейтить без вычисления второго аргумента, то да, все так. Но дело-то не в этом.

18. 0xd34df00d0xd34df00d /17 17.10.2012 13:52 Azoth_primary

Имеется ввиду, конечно же, «иногда можно».

19. kbDZhon /16 17.10.2012 13:52 04a3831c

что, правда есть понятие "энергичный режим"?

20. DZhonkb /19 17.10.2012 13:53 STARGATE

ок, энергичные вычисления

21. kb0xd34df00d /17 17.10.2012 13:53

ну об этом же и вся речь

22. kbDZhon /20 17.10.2012 13:54

ну, ок. я думал издеваешься.

23. kb0xd34df00d /18 17.10.2012 13:55

ага, и еще прикол в том, что с foldl это сделать "никогда нельзя".

24. DZhonkb /22 17.10.2012 13:55 STARGATE

я добрый хуй

25. kbDZhon /24 17.10.2012 13:56 04a3831c

звучит как кавер на песню найка борзова

26. 0xd34df00dkb /25 17.10.2012 13:56 Azoth_primary

Никогда не слушал Найка Борзова.

27. kb0xd34df00d /26 17.10.2012 13:56 04a3831c

ну там про куркуму в роли лошади

28. DZhonkb /25 17.10.2012 13:57 STARGATE

Звучит как откровенное признание
!

29. 0xd34df00dkb /27 17.10.2012 13:57 Azoth_primary

А, заебись.

30. 0xd34df00dDZhon /28 17.10.2012 13:57 Azoth_primary

Звучит как пойдем попилить личкрафты
;]

31. DZhon0xd34df00d /30 17.10.2012 13:58 STARGATE

Непристойное предложение.

32. 0xd34df00dDZhon /31 17.10.2012 13:58 Azoth_primary

Ж(

33. DZhon0xd34df00d /32 17.10.2012 14:03 STARGATE

Ты должен привлечь разработчика! Будь мужиком, не мямли, пригласи его на ревью. Однажды он зайдет к тебе на гитхаб и у вас будет жаркий merge.

34. 238328 17.10.2012 15:19 29663622141350479727440860

я ленивый и поэтому не тыкаю хаскелль, всем советую

35. gds238328 /34 17.10.2012 16:49

кстати да, не тыкать х-ь — это мета-ленивое программирование на х-е.

36. gds 17.10.2012 16:51

в целом, нужно очень хорошо понимать, что делаешь и что там внутри творится, когда ленивые вычисления сознательно используются для прерывания прохождения большого набора данных и для кое-каких подобных вещей.
Может "клитор в цепь засосать", в результате — типичное поведение типичных х-евых поделок в реальных условиях — пережор памяти.

37. kbgds /36 18.10.2012 20:51

Ну я благодаря SICP'у (и, в частности, главе, где ленивый интерпретатор писался), наверное, и въехал без совсем уж перелома костей. Так бы фиг осознал, наверное.

Do you really want to delete ?