diff --git a/src/Data/List.purs b/src/Data/List.purs index bbb532e..c5c2450 100644 --- a/src/Data/List.purs +++ b/src/Data/List.purs @@ -733,10 +733,11 @@ instance foldableList :: Foldable List where instance unfoldableList :: Unfoldable List where - unfoldr f b = go (f b) + unfoldr f b = go b Nil where - go Nothing = Nil - go (Just (Tuple a b)) = Cons a (go (f b)) + go source memo = case f source of + Nothing -> reverse memo + Just (Tuple one rest) -> go rest (Cons one memo) instance traversableList :: Traversable List where traverse _ Nil = pure Nil diff --git a/test/Test/Data/List.purs b/test/Test/Data/List.purs index 0a23ff0..83e4dff 100644 --- a/test/Test/Data/List.purs +++ b/test/Test/Data/List.purs @@ -287,6 +287,12 @@ testList = do log "foldMap should be left-to-right" assert $ foldMap show (range 1 5) == "12345" + log "unfoldr should be stack-safe" + void $ pure $ length $ Data.Unfoldable.replicate 100000 1 + + log "unfoldr should maintain order" + assert $ (1..5) == Data.Unfoldable.unfoldr step 1 + -- log "can find the first 10 primes using lazy lists" -- let eratos :: L.List Number -> L.List Number -- eratos xs = Control.Lazy.defer \_ -> @@ -299,6 +305,10 @@ testList = do -- primes = eratos $ upFrom 2 -- assert $ L.fromList (L.take 10 primes) == [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] +step :: Int -> Maybe (Tuple Int Int) +step 6 = Nothing +step n = Just (Tuple n (n + 1)) + nil :: List Int nil = Nil