Skip to content

Commit 3d864d1

Browse files
authored
Merge pull request #152 from garyb/unfoldable1
Add `Unfoldable1` instances for non-empty lists
2 parents ad31f0a + 4b9e47e commit 3d864d1

File tree

4 files changed

+30
-5
lines changed

4 files changed

+30
-5
lines changed

src/Data/List/Lazy/Types.purs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import Data.Ord (class Ord1, compare1)
2323
import Data.Traversable (class Traversable, traverse, sequence)
2424
import Data.TraversableWithIndex (class TraversableWithIndex, traverseWithIndex)
2525
import Data.Tuple (Tuple(..), snd)
26-
import Data.Unfoldable (class Unfoldable)
26+
import Data.Unfoldable (class Unfoldable, unfoldr1)
2727
import Data.Unfoldable1 (class Unfoldable1)
2828

2929
-- | A lazy linked list.
@@ -270,6 +270,9 @@ instance traversableNonEmptyList :: Traversable NonEmptyList where
270270
sequence (NonEmptyList nel) =
271271
map (\xxs -> NonEmptyList $ defer \_ -> xxs) $ sequence (force nel)
272272

273+
instance unfoldable1NonEmptyList :: Unfoldable1 NonEmptyList where
274+
unfoldr1 f b = NonEmptyList $ defer \_ -> unfoldr1 f b
275+
273276
instance functorWithIndexNonEmptyList :: FunctorWithIndex Int NonEmptyList where
274277
mapWithIndex f (NonEmptyList ne) = NonEmptyList $ defer \_ -> mapWithIndex (f <<< maybe 0 (add 1)) $ force ne
275278

src/Data/List/Types.purs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ derive newtype instance traversableNonEmptyList :: Traversable NonEmptyList
213213

214214
derive newtype instance foldable1NonEmptyList :: Foldable1 NonEmptyList
215215

216+
derive newtype instance unfoldable1NonEmptyList :: Unfoldable1 NonEmptyList
217+
216218
instance functorWithIndexNonEmptyList :: FunctorWithIndex Int NonEmptyList where
217219
mapWithIndex fn (NonEmptyList ne) = NonEmptyList $ mapWithIndex (fn <<< maybe 0 (add 1)) ne
218220

test/Test/Data/List/Lazy.purs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import Data.NonEmpty ((:|))
1414
import Data.Traversable (traverse)
1515
import Data.TraversableWithIndex (traverseWithIndex)
1616
import Data.Tuple (Tuple(..))
17-
import Data.Unfoldable (unfoldr)
17+
import Data.Unfoldable (replicate1, unfoldr)
1818
import Data.Unfoldable1 (unfoldr1)
1919
import Effect (Effect)
2020
import Effect.Console (log)
@@ -427,6 +427,12 @@ testListLazy = do
427427
log "map should maintain order"
428428
assert $ (1..5) == map identity (1..5)
429429

430+
log "unfoldable replicate1 should be stack-safe for NEL"
431+
void $ pure $ NEL.length $ (replicate1 100000 1 :: NEL.NonEmptyList Int)
432+
433+
log "unfoldr1 should maintain order for NEL"
434+
assert $ (nel (1 :| l [2, 3, 4, 5])) == unfoldr1 step1 1
435+
430436
step :: Int -> Maybe (Tuple Int Int)
431437
step 6 = Nothing
432438
step n = Just (Tuple n (n + 1))

test/Test/Data/List/NonEmpty.purs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@ module Test.Data.List.NonEmpty (testNonEmptyList) where
22

33
import Prelude
44

5-
import Effect (Effect)
6-
import Effect.Console (log)
75
import Data.Foldable (class Foldable, foldM, foldMap, foldl, length)
86
import Data.FoldableWithIndex (foldlWithIndex, foldrWithIndex, foldMapWithIndex)
9-
import Data.TraversableWithIndex (traverseWithIndex)
107
import Data.List as L
118
import Data.List.NonEmpty as NEL
129
import Data.Maybe (Maybe(..))
1310
import Data.Monoid.Additive (Additive(..))
1411
import Data.NonEmpty ((:|))
12+
import Data.TraversableWithIndex (traverseWithIndex)
1513
import Data.Tuple (Tuple(..))
14+
import Data.Unfoldable (replicate, replicate1, unfoldr, unfoldr1)
15+
import Effect (Effect)
16+
import Effect.Console (log)
1617
import Test.Assert (assert)
1718

1819
testNonEmptyList :: Effect Unit
@@ -265,6 +266,19 @@ testNonEmptyList = do
265266
assert $ map (traverseWithIndex (\i a -> Just $ i + a)) (NEL.fromFoldable [2, 2, 2])
266267
== Just (NEL.fromFoldable [2, 3, 4])
267268

269+
log "unfoldable replicate1 should be stack-safe"
270+
void $ pure $ NEL.length $ (replicate1 100000 1 :: NEL.NonEmptyList Int)
271+
272+
log "unfoldr1 should maintain order"
273+
assert $ (nel 1 [2, 3, 4, 5]) == unfoldr1 step1 1
274+
275+
step :: Int -> Maybe (Tuple Int Int)
276+
step 6 = Nothing
277+
step n = Just (Tuple n (n + 1))
278+
279+
step1 :: Int -> Tuple Int (Maybe Int)
280+
step1 n = Tuple n (if n >= 5 then Nothing else Just (n + 1))
281+
268282
odd :: Int -> Boolean
269283
odd n = n `mod` 2 /= zero
270284

0 commit comments

Comments
 (0)