Entry tags:
Куда прячется ленивость и как ее оттуда достать?
Мы привыкли, что правая свертка (foldr) хорошо заточена для работы с бесконечными списками:
> let mapPlusPi = foldr (\x xs -> (x+pi):xs) [] > head $ mapPlusPi [1..] 4.141592653589793К сожалению, иногда возникают неприятности. Вот функция, которая берет список и выкидывает из него элементы стоящие на нечетных местах:
> let evenOnly = snd . foldr (\x (os,es) -> (x:es,os)) ([],[]) > evenOnly [1..10] [2,4,6,8,10]Только вот на бесконечном списке она ведет себя неподобающе
> head $ evenOnly [1..] Interrupted.Почему это происходит, и какие минимальные изменения можно в нее внести, чтобы восстановить утраченную работоспособность?
no subject
no subject
no subject
let evenOnly = snd . foldr (\x z -> let (os,es) = z in (x:es,os)) ([],[])
В оригинальном примере явный pattern matching в параметре автоматически делает функцию строгой по второму аргументу. Что происходит внутри -- хорошо видно при вызове ghc -O -ddump-stranal. В первом случае demand на параметер -- (S,1*U), во втором -- (L,U(1*U,1*U)).
no subject
а почему именно - надо подумать.
no subject
Т.е. например вот здесь:
let bla = foldr(\x (y:t) -> x:t) [0]
понятно, что поскольку у списка есть два конструктора, то нужно убедиться, что y:t, а не []. А вот у тупля только один конструктор, так что, не ясно, что его останавливает лениво матчить.
no subject
no subject
no subject
no subject
большая непривычность (но не сложность!) рассуждения за costs semantics.
Что довольно сильно, не буду спорить.
no subject
" = "
no subject
no subject
no subject
И какой же это язык надо знать, тов. недубина?
no subject