Commits

Bryan O'Sullivan committed dadde80

Implement and test accumulating maps

Comments (0)

Files changed (2)

Data/Text/Lazy.hs

     -- , scanr1
 
     -- ** Accumulating maps
-    -- , mapAccumL
-    -- , mapAccumR
+    , mapAccumL
+    , mapAccumR
 
     -- ** Generation and unfolding
     -- , replicate
                 Just (t,ts) -> scanl f t ts
 {-# INLINE scanl1 #-}
 
+-- | /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'.
+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
+
+-- | The 'mapAccumR' function behaves like a combination of 'map' and
+-- 'foldr'; it applies a function to each element of a 'Text', passing
+-- an accumulating parameter from right to left, and returning a final
+-- value of this accumulator together with the new 'Text'.
+mapAccumR :: (a -> Char -> (a,Char)) -> a -> Text -> (a, Text)
+mapAccumR 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) = mapAccumR f s xs
+
 -- | /O(n)/ 'splitAt' @n t@ returns a pair whose first element is a
 -- prefix of @t@ of length @n@, and whose second is the remainder of
 -- the string. It is equivalent to @('take' n t, 'drop' n t)@.

tests/Properties.hs

 
 prop_T_mapAccumL f z   = L.mapAccumL f z `eqP` (second unpackT . T.mapAccumL f z)
     where types = f :: Int -> Char -> (Int,Char)
+prop_TL_mapAccumL f z  = L.mapAccumL f z `eqP` (second unpackT . TL.mapAccumL f z)
+    where types = f :: Int -> Char -> (Int,Char)
 prop_T_mapAccumR f z   = L.mapAccumR f z `eqP` (second unpackT . T.mapAccumR f z)
     where types = f :: Int -> Char -> (Int,Char)
+prop_TL_mapAccumR f z   = L.mapAccumR f z `eqP` (second unpackT . TL.mapAccumR f z)
+    where types = f :: Int -> Char -> (Int,Char)
 
 prop_T_replicate n     = L.replicate n `eq`   (unpackT . T.replicate n)
 prop_T_unfoldr n       = L.unfoldr f   `eq`   (unpackT . T.unfoldr f)
   ("prop_T_scanr1", mytest prop_T_scanr1),
 
   ("prop_T_mapAccumL", mytest prop_T_mapAccumL),
+  ("prop_TL_mapAccumL", mytest prop_TL_mapAccumL),
   ("prop_T_mapAccumR", mytest prop_T_mapAccumR),
+  ("prop_TL_mapAccumR", mytest prop_TL_mapAccumR),
 
   ("prop_T_replicate", mytest prop_T_replicate),
   ("prop_T_unfoldr", mytest prop_T_unfoldr),