Commits

Bryan O'Sullivan committed 62868c7

Reimplement mapAccumL properly.

Comments (0)

Files changed (3)

 -- | /O(n)/ Like a combination of 'map' and 'foldl'. Applies a
 -- function to each element of a 'Text', passing an accumulating
 -- parameter from left to right, and returns a final 'Text'.
---
--- /Note/: Unlike the version over lists, this function does not return a
--- final value for the accumulator.
-mapAccumL :: (a -> Char -> (a,Char)) -> a -> Text -> Text
-mapAccumL f z t = unstream (S.mapAccumL f z (stream t))
-{-# INLINE mapAccumL #-}
+mapAccumL :: (a -> Char -> (a,Char)) -> a -> Text -> (a, Text)
+mapAccumL f s t = case uncons t of
+                    Nothing -> (s, empty)
+                    Just (x, xs) -> (s'', cons y ys)
+                        where (s', y ) = f s x
+                              (s'',ys) = mapAccumL f s' xs
 
 -- -----------------------------------------------------------------------------
 -- ** Generating and unfolding 'Text's
 -- -----------------------------------------------------------------------------
 -- ** Accumulating maps
 
-mapAccumL :: (a -> Char -> (a,Char)) -> a -> Stream Char -> Stream Char
+-- | /O(n)/ Like a combination of 'map' and 'foldl'. Applies a
+-- function to each element of a stream, passing an accumulating
+-- parameter from left to right, and returns a final stream.
+--
+-- /Note/: Unlike the version over lists, this function does not
+-- return a final value for the accumulator, because the nature of
+-- streams precludes it.
+mapAccumL :: (a -> b -> (a,b)) -> a -> Stream b -> Stream b
 mapAccumL f z0 (Stream next0 s0 len) = Stream next (s0 :!: z0) len
   where
     {-# INLINE next #-}
 prop_scanr f z       = L.scanr f z   `eqP`  (unpack . T.scanr f z)
 prop_scanr1 f        = L.scanr1 f    `eqP`  (unpack . T.scanr1 f)
 
-prop_mapAccumL f z   = (snd . L.mapAccumL f z)`eqP` (unpack . T.mapAccumL f z)
+prop_mapAccumL f z   = L.mapAccumL f z `eqP` (second unpack . T.mapAccumL f z)
     where types = f :: Int -> Char -> (Int,Char)
 
 prop_replicate n     = L.replicate n `eq`   (unpack . T.replicate n)