Big problem with not big list
xgrommx opened this issue · 1 comments
xgrommx commented
Hello everyone! I have some experiments with lazy list. But I have some problem.
module Main where
import Prelude (Unit, map, mod, show, ($), (*), (+), (/=), (<<<), (<=))
import Data.List.Lazy (all, filter, repeat, take, iterate, length, takeWhile, (:))
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, log)
import Data.Lazy (defer, force)
main :: Eff (console::CONSOLE) Unit
main = do
-- log <<< show <<< length <<< take 1000000 <<< map (_+10) <<< repeat $ 1 -- works
-- log <<< show <<< length <<< take 10000000 <<< map (_+10) <<< repeat $ 1 -- hard
-- log <<< show <<< length <<< take 100000000 <<< map (_+10) <<< repeat $ 1 -- oh my...
-- log <<< show <<< length <<< take 100000 <<< iterate(_+1) $ 1 -- Maximum call stack size exceeded
-- log <<< show <<< length <<< take 10000 <<< iterate(_+1) $ 1 -- Maximum call stack size exceeded
log <<< show <<< length <<< take 1000 <<< iterate(_+1) $ 1 -- only this code works!!!As u can see iterate has some strange behavior. I think this problem in map here https://github.com/purescript/purescript-lists/blob/master/src/Data/List/Lazy.purs#L189
Or maybe I don't know how use lazy list in purescript. If it is, please help me =)
matil019 commented
Nice to meet you everyone! I came across the same problem. It seems that it is iterate that is not stack-safe.
An alternative, hand-made implementation of mine seems to work:
myIterate :: forall a. (a -> a) -> a -> List a
myIterate f x = List $ defer \_ -> Cons x (myIterate f (f x))
main = log <<< show <<< length <<< take 100000 <<< myIterate(_+1) $ 1
-- prints 100000