Skip to content

Commit 28f3eec

Browse files
committed
Merge pull request #42 from zudov/stack-safe
Make functions in Data.List stack-safe
2 parents e3eaed5 + e484baa commit 28f3eec

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

src/Data/List.purs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,7 @@ null _ = false
185185
-- |
186186
-- | Running time: `O(n)`
187187
length :: forall a. List a -> Int
188-
length Nil = 0
189-
length (Cons _ xs) = 1 + length xs
188+
length = foldl (\acc _ -> acc + 1) 0
190189

191190
--------------------------------------------------------------------------------
192191
-- Extending arrays ------------------------------------------------------------
@@ -712,10 +711,11 @@ instance functorList :: Functor List where
712711
instance foldableList :: Foldable List where
713712
foldr _ b Nil = b
714713
foldr o b (Cons a as) = a `o` foldr o b as
715-
foldl _ b Nil = b
716-
foldl o b (Cons a as) = foldl o (b `o` a) as
717-
foldMap _ Nil = mempty
718-
foldMap f (Cons x xs) = f x <> foldMap f xs
714+
foldl = go
715+
-- FIXME: Helper function is needed until purescript/purescript#1413 is fixed
716+
where go _ b Nil = b
717+
go o b (Cons a as) = go o (b `o` a) as
718+
foldMap f = foldl (\acc -> append acc <<< f) mempty
719719

720720
instance unfoldableList :: Unfoldable List where
721721
unfoldr f b = go (f b)

test/Test/Data/List.purs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
module Test.Data.List (testList) where
22

33
import Prelude
4+
import Control.Monad
45
import Control.Monad.Eff.Console (log)
6+
import Data.Foldable
7+
import Data.Monoid.Additive
58
import Data.List
69
import Data.Maybe (Maybe(..), isNothing)
710
import Data.Maybe.Unsafe (fromJust)
@@ -46,6 +49,9 @@ testList = do
4649
assert $ length (toList [1]) == 1
4750
assert $ length (toList [1, 2, 3, 4, 5]) == 5
4851

52+
log "length should be stack-safe"
53+
void $ pure $ length (range 1 100000)
54+
4955
log "snoc should add an item to the end of an list"
5056
assert $ toList [1, 2, 3] `snoc` 4 == toList [1, 2, 3, 4]
5157
assert $ nil `snoc` 1 == toList [1]
@@ -271,6 +277,15 @@ testList = do
271277
assert $ foldM (\x y -> Just (x + y)) 0 (range 1 10) == Just 55
272278
assert $ foldM (\_ _ -> Nothing) 0 (range 1 10) == Nothing
273279

280+
log "foldl should be stack-safe"
281+
void $ pure $ foldl (+) 0 $ range 1 100000
282+
283+
log "foldMap should be stack-safe"
284+
void $ pure $ foldMap Additive $ range 1 100000
285+
286+
log "foldMap should be left-to-right"
287+
assert $ foldMap show (range 1 5) == "12345"
288+
274289
-- log "can find the first 10 primes using lazy lists"
275290
-- let eratos :: L.List Number -> L.List Number
276291
-- eratos xs = Control.Lazy.defer \_ ->

0 commit comments

Comments
 (0)