Skip to content

Commit a49621c

Browse files
authored
Merge pull request #139 from ibara1454/issue138
Don't force more than necessary in Data.List.Lazy take
2 parents d44e568 + 8229f7e commit a49621c

File tree

2 files changed

+9
-2
lines changed

2 files changed

+9
-2
lines changed

src/Data/List/Lazy.purs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -509,10 +509,11 @@ slice start end xs = take (end - start) (drop start xs)
509509
-- |
510510
-- | Running time: `O(n)` where `n` is the number of elements to take.
511511
take :: forall a. Int -> List a -> List a
512-
take n = List <<< map (go n) <<< unwrap
512+
take n = if n <= 0
513+
then const nil
514+
else List <<< map (go n) <<< unwrap
513515
where
514516
go :: Int -> Step a -> Step a
515-
go i _ | i <= 0 = Nil
516517
go _ Nil = Nil
517518
go n' (Cons x xs) = Cons x (take (n' - 1) xs)
518519

test/Test/Data/List/Lazy.purs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,12 @@ testListLazy = do
272272
assert $ (take 2 (l [1, 2, 3])) == l [1, 2]
273273
assert $ (take 1 nil') == nil'
274274

275+
log "take should evaluate exactly n items which we needed"
276+
assert let oops x = 0 : oops x
277+
xs = 1 : defer oops
278+
in take 1 xs == l [1]
279+
-- If `take` evaluate more than once, it would crash with a stack overflow
280+
275281
log "takeWhile should keep all values that match a predicate from the front of an list"
276282
assert $ (takeWhile (_ /= 2) (l [1, 2, 3])) == l [1]
277283
assert $ (takeWhile (_ /= 3) (l [1, 2, 3])) == l [1, 2]

0 commit comments

Comments
 (0)