Data.List.inits is not lazy
Jan. 29th, 2013 08:50 pmтак и задумано, что ли?
а чо не так:
Пример:
Если пользоваться Data.List.inits, виснет.
(всякие last и вообще inits - не за эффективностью гоняюсь, а за пониманием extend ли это)
Upd: видимо баг. У меня 7.0.3, пора обновлять.
а чо не так:
inits xs = [] : inits' xs where
inits' xs = case xs of
[] -> []
x: xs' -> [x]: (map (x :) $ inits' xs')Пример:
import Data.List hiding (unfoldr, inits)
inits xs = [] : inits' xs where
inits' xs = case xs of
[] -> []
x: xs' -> [x]: (map (x :) $ inits' xs')
ext :: ([b]->a)->[b]->[a] -- extend
ext f ys = map f $ inits ys -- Data.List.inits is not lazy
unfoldr f x = map fst bs where
bs = concat $ takeWhile (/=[]) $ map f as
as = ext g bs
g [] = x
g bs = snd $ last bs
main = print $ unfoldr (\xs -> if null xs then [] else [splitAt 2 xs]) [1..9]Если пользоваться Data.List.inits, виснет.
(всякие last и вообще inits - не за эффективностью гоняюсь, а за пониманием extend ли это)
Upd: видимо баг. У меня 7.0.3, пора обновлять.
no subject
Date: 2013-01-29 09:28 pm (UTC)Prelude> :m +Data.List
Prelude Data.List> let ext f = map f . inits
Prelude Data.List> take 5 $ ext sum [1..]
[0,1,3,6,10]
ЧЯДНТ?
Оно же scanl:
Prelude> take 5 $ scanl (+) 0 [1..]
[0,1,3,6,10]
no subject
Date: 2013-01-29 09:49 pm (UTC)Если дело не в ленивости, то почему мой пример виснет (точнее, валится с <<loop>>), если я пользуюсь Data.List.inits, а не определяю свой. Я так понимаю, что inits "тянет" из ys лишнее значение, которого не может быть.
(У меня вообще-то через foldr аккуратненький вариант есть:
unfoldr f x = ys where (ys, ts) = unzip $ concat $ foldr (g . f) [] (x:ts) g y r = if null y then [] else y:rя просто изучаю, как unfoldr и extend связаны)no subject
Date: 2013-01-29 09:53 pm (UTC)Prelude Data.List> let ext = \f -> map f . inits
Prelude Data.List> take 5 $ ext sum [1,2,3,4,5,undefined]
[0,1,3,6,10]
Prelude Data.List> let bot = bot in bot
Interrupted.
Prelude Data.List> let bot = bot
Prelude Data.List> bot
Interrupted.
Prelude Data.List> take 5 $ ext sum [1,2,3,4,5,bot]
[0,1,3,6,10]
no subject
Date: 2013-01-29 09:59 pm (UTC)no subject
Date: 2013-01-29 10:07 pm (UTC)import Data.List hiding (unfoldr) {- inits xs = [] : inits' xs where inits' xs = case xs of [] -> [] x: xs' -> [x]: (map (x :) $ inits' xs') -} ext :: ([b]->a)->[b]->[a] -- extend ext f ys = map f $ inits ys -- Data.List.inits is not lazy unfoldr f x = map fst bs where bs = concat $ takeWhile (/=[]) $ map f as as = ext g bs g [] = x g bs = snd $ last bs main = print $ unfoldr (\xs -> if null xs then [] else [splitAt 2 xs]) [1..9]no subject
Date: 2013-01-29 10:11 pm (UTC)no subject
Date: 2013-01-29 09:51 pm (UTC)no subject
Date: 2013-01-29 09:55 pm (UTC)И чем вас такой unfoldr не устраивает (с [] вместо Nothing)?И ещё - если кажется, что сплющивать придётся, вам надо на list monad смотреть, может это ближе будет, чем unfoldr/extend.
Вот ещё няшный комонадический unfoldW
import Data.List
extend f ys = map f $ inits ys
unfoldW wf w = fst (wf w) : unfoldW wf (extend (snd . wf) w)
main = take 5 $ unfoldW (\x -> (sum x, 5)) [1..2]
no subject
Date: 2013-01-29 10:29 pm (UTC)А пример unfoldr классный, конечно. Я на простую рекурсию как-то и не глянул.
no subject
Date: 2013-01-29 10:32 pm (UTC)no subject
Date: 2013-01-29 10:30 pm (UTC)no subject
Date: 2013-01-29 10:34 pm (UTC)no subject
Date: 2013-01-29 10:47 pm (UTC)no subject
Date: 2013-01-30 10:27 am (UTC)хахаха, у меня вчера по этому поводу тоже истерика была - я как раз вариант первой ссылки до того почитал. По типу должна быть extend (f . extract) :) Спасибо, вторая ссылка подтвердила.
А ещё, если extend f ys = map f $ inits ys, то как же выглядит extract? inits же начинается с [], а как из него что-то получить не ясно (например, чтобы extend extract = id). (допустим, extend f = map f . tail . inits - там вроде бы ясно, extract = last)
no subject
Date: 2013-01-30 12:10 pm (UTC)См. http://stackoverflow.com/a/12537659/805266
As noted in the comments, you cannot have a comonad instance for lists that may be empty since coreturn has to return something.