Skip to content

Commit 886d3a7

Browse files
authored
Safe traverse, fix #86 (#87)
* Safe traverse, fix #86 * Sort imports
1 parent 48ca7c5 commit 886d3a7

File tree

2 files changed

+10
-12
lines changed

2 files changed

+10
-12
lines changed

src/Data/List/Types.purs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
11
module Data.List.Types where
22

33
import Prelude
4-
54
import Control.Alt (class Alt)
65
import Control.Alternative (class Alternative)
6+
import Control.Apply (lift2)
77
import Control.Comonad (class Comonad)
88
import Control.Extend (class Extend)
99
import Control.MonadPlus (class MonadPlus)
1010
import Control.MonadZero (class MonadZero)
1111
import Control.Plus (class Plus)
12-
1312
import Data.Foldable (class Foldable, foldr, foldl, intercalate)
1413
import Data.Generic (class Generic)
1514
import Data.Maybe (Maybe(..))
1615
import Data.Monoid (class Monoid, mempty)
1716
import Data.Newtype (class Newtype)
1817
import Data.NonEmpty (NonEmpty, (:|))
1918
import Data.NonEmpty as NE
20-
import Data.Traversable (class Traversable, traverse, sequence)
19+
import Data.Traversable (class Traversable, traverse)
2120
import Data.Tuple (Tuple(..))
2221
import Data.Unfoldable (class Unfoldable)
2322

@@ -79,10 +78,8 @@ instance unfoldableList :: Unfoldable List where
7978
Just (Tuple one rest) -> go rest (one : memo)
8079

8180
instance traversableList :: Traversable List where
82-
traverse _ Nil = pure Nil
83-
traverse f (a : as) = Cons <$> f a <*> traverse f as
84-
sequence Nil = pure Nil
85-
sequence (a : as) = Cons <$> a <*> sequence as
81+
traverse f = map (foldl (flip (:)) Nil) <<< foldl (\acc -> lift2 (flip (:)) acc <<< f) (pure Nil)
82+
sequence = traverse id
8683

8784
instance applyList :: Apply List where
8885
apply Nil _ = Nil

test/Test/Data/List.purs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
11
module Test.Data.List (testList) where
22

33
import Prelude
4-
4+
import Data.List.NonEmpty as NEL
55
import Control.Monad.Eff (Eff)
66
import Control.Monad.Eff.Console (CONSOLE, log)
7-
87
import Data.Foldable (foldMap, foldl)
98
import Data.List (List(..), (..), length, range, foldM, unzip, zip, zipWithA, zipWith, intersectBy, intersect, (\\), deleteBy, delete, unionBy, union, nubBy, nub, groupBy, group', group, span, dropWhile, drop, takeWhile, take, sortBy, sort, catMaybes, mapMaybe, filterM, filter, concat, concatMap, reverse, alterAt, modifyAt, updateAt, deleteAt, insertAt, findLastIndex, findIndex, elemLastIndex, elemIndex, (!!), uncons, init, tail, last, head, insertBy, insert, snoc, null, singleton, fromFoldable, transpose, mapWithIndex, (:))
10-
import Data.List.NonEmpty as NEL
119
import Data.Maybe (Maybe(..), isNothing, fromJust)
1210
import Data.Monoid.Additive (Additive(..))
1311
import Data.NonEmpty ((:|))
12+
import Data.Traversable (traverse)
1413
import Data.Tuple (Tuple(..))
1514
import Data.Unfoldable (replicate, replicateA, unfoldr)
16-
1715
import Partial.Unsafe (unsafePartial)
18-
1916
import Test.Assert (ASSERT, assert)
2017

2118
testList :: forall eff. Eff (assert :: ASSERT, console :: CONSOLE | eff) Unit
@@ -318,6 +315,10 @@ testList = do
318315
log "transpose (singleton Nil) == Nil"
319316
assert $ transpose (singleton Nil) == (Nil :: List (List Int))
320317

318+
log "traverse should be stack-safe"
319+
let xs = fromFoldable (range 1 100000)
320+
assert $ traverse Just xs == Just xs
321+
321322
step :: Int -> Maybe (Tuple Int Int)
322323
step 6 = Nothing
323324
step n = Just (Tuple n (n + 1))

0 commit comments

Comments
 (0)