diff --git a/src/Data/List/Types.purs b/src/Data/List/Types.purs index 55467db..6f32fa6 100644 --- a/src/Data/List/Types.purs +++ b/src/Data/List/Types.purs @@ -1,15 +1,14 @@ module Data.List.Types where import Prelude - import Control.Alt (class Alt) import Control.Alternative (class Alternative) +import Control.Apply (lift2) import Control.Comonad (class Comonad) import Control.Extend (class Extend) import Control.MonadPlus (class MonadPlus) import Control.MonadZero (class MonadZero) import Control.Plus (class Plus) - import Data.Foldable (class Foldable, foldr, foldl, intercalate) import Data.Generic (class Generic) import Data.Maybe (Maybe(..)) @@ -17,7 +16,7 @@ import Data.Monoid (class Monoid, mempty) import Data.Newtype (class Newtype) import Data.NonEmpty (NonEmpty, (:|)) import Data.NonEmpty as NE -import Data.Traversable (class Traversable, traverse, sequence) +import Data.Traversable (class Traversable, traverse) import Data.Tuple (Tuple(..)) import Data.Unfoldable (class Unfoldable) @@ -79,10 +78,8 @@ instance unfoldableList :: Unfoldable List where Just (Tuple one rest) -> go rest (one : memo) instance traversableList :: Traversable List where - traverse _ Nil = pure Nil - traverse f (a : as) = Cons <$> f a <*> traverse f as - sequence Nil = pure Nil - sequence (a : as) = Cons <$> a <*> sequence as + traverse f = map (foldl (flip (:)) Nil) <<< foldl (\acc -> lift2 (flip (:)) acc <<< f) (pure Nil) + sequence = traverse id instance applyList :: Apply List where apply Nil _ = Nil diff --git a/test/Test/Data/List.purs b/test/Test/Data/List.purs index 8809338..37d6610 100644 --- a/test/Test/Data/List.purs +++ b/test/Test/Data/List.purs @@ -1,21 +1,18 @@ module Test.Data.List (testList) where import Prelude - +import Data.List.NonEmpty as NEL import Control.Monad.Eff (Eff) import Control.Monad.Eff.Console (CONSOLE, log) - import Data.Foldable (foldMap, foldl) 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, (:)) -import Data.List.NonEmpty as NEL import Data.Maybe (Maybe(..), isNothing, fromJust) import Data.Monoid.Additive (Additive(..)) import Data.NonEmpty ((:|)) +import Data.Traversable (traverse) import Data.Tuple (Tuple(..)) import Data.Unfoldable (replicate, replicateA, unfoldr) - import Partial.Unsafe (unsafePartial) - import Test.Assert (ASSERT, assert) testList :: forall eff. Eff (assert :: ASSERT, console :: CONSOLE | eff) Unit @@ -318,6 +315,10 @@ testList = do log "transpose (singleton Nil) == Nil" assert $ transpose (singleton Nil) == (Nil :: List (List Int)) + log "traverse should be stack-safe" + let xs = fromFoldable (range 1 100000) + assert $ traverse Just xs == Just xs + step :: Int -> Maybe (Tuple Int Int) step 6 = Nothing step n = Just (Tuple n (n + 1))